That idea may be logic but i don't think he has the skills to be a good teacher. Just because we know something that doesn't makes us smart to teach it.
That's really very basic stuff. Bit tricks go a lot further than this in the real world, it's a heap of fun! Just as an exercise for you: try to think of a way to swap two variables without using a temporary variable, but by just using bit operations. Or have a look at a fast bitcount, etc.
This brings back a lot of memories. It was like 2000 or 2001 and I was learning C using books and a compiler written in the 80s! (Borland Turbo C/C++ 1.1) I still have a great sense of nostalgia for that blue background with chunky yellow text and seeing functions written in that glorious font with pointers that poke and peek directly into memory and occasionally prodding hardware registers brings back some fond memories. Thanks , Dave!
Wow, that was really close to when I was doing the same thing, except I found DJGPP, the GNU 32bit DOS compiler, which was used to make Quake as well. Definitely brings back memories for me as well! Loved coding my own graphics like this, and the GNU compiler made it so much easier as you didn't have to worry about things like long jumps, memory boundaries etc... DJGPP handled all that for you.
@@NeilRoy Ha, yeah! I discovered DJGPP a year or so later. It really opened up a lot of options since I was no longer limited to a measly 640k of RAM. Though I think it came at the cost of operating in protected mode which meant you couldn't quite access memory with the same directness as before.
Greetings from San Francisco. I thought there were no time machines, but you just brought me back to 1979. I loved it the first time around, and I'm (almost) ready to break out my Poly88 with a Cromemco Dazzler and write code along with you. Almost... but sanity prevailed. Dave, you are a BAD influence. I can't wait for your next stroll through my faded youth.
I remember implementing the Bresenham circle algorithm in assembly and also figuring out the math behind it when I was in 8th or 9th grade where I had just learnt the the Pythagorean theorem. It was so awesome :)
You can speed up that Bresenham's implementation considerably by avoiding calls to SETPIXEL. Instead, translate the x,y starting point to a byte address and a mask (as done within SETPIXEL), and within the loop, treat x moves as shifts of that mask (adding/subtracting one to the byte offset if the mask becomes 0), and treat y moves as adjustments (add/subtract BYTESPERROW) of the byte address. Back in the day (circa 1985 with an EGA/VGA adapter on a PC running MS-DOS) I had an assembly language Bresenham's that was nearly as fast as a NEC 7220 based board. Also, for a lot of applications (I was doing CAD work at the time), it is well worth the minimal effort to optimize horizontal and vertical lines.
Back on my CGA machine I was doing just that. I started with a setpixel (ASM inside of C code). That was about 200x faster than the built in command.. I started with this level of simple line command, setting every pixel of the line. Then improved it with a look at how many bits in a byte are set and did them all at once. Fun times!!
@@hrayz Yeah, BGI, Borland's graphics library, was useless. It was nice and compatible, but useless in terms of speed. And couldn't access MCGA / 256-colour mode. Better to just set a big pointer to graphics RAM and do it yourself.
This reminds me so much of when I was a kid programming different early machines that did not have any built in graphics like the early Atari and TRS80. I love it, please make more videos like this one. Thank you very much.
A few years ago I wrote a graphics primitive library for Arduino driving a 20*10RGB led array. This was used in a series of digital art workshops as part of our National Arts Festival. The best of the art was later displayed on our huge Rgb periodic table display. Each element was about 6x6” . Since the pixels were wired in an odd order I created a translation table to translate x/y to pixel number. Fun times.
I love the fact that you are probably going to be the only human on this planet running this code, but you still have sanity checks to ensure that you're not going outside of screen memory. The force of habit from a person who has had to reflexively sanitize inputs his entire life.
Loved this! Man, this takes me back. I still prefer to program in C (not C++) to this day, usually using a GNU compiler which supports the newer versions of C. I remember programming graphics in DOS on my old computer in the 1990s. I wrote my own graphics library much like you have here by accessing A000 etc... as I learned I added more functions to it for lines, some optimized functions for straight lines (I think that used memset commands to set larger amounts at once). I loved those days and the fact that it wasn't done for you. I created a free game called Deluxe Pacman 1 & 2 for DOS, older Windows and modern Windows (last tested on Windows 10) and it is coded entirely using C (no plusses), only it uses the Allegro library (I honestly wish I had done it entirely on my own and never used a library). Good times anyhow. Oh, and I used to use DJGPP for DOS back then, it handled the memory limitations for you, so no worries about things like long jumps and the like. I believe Quake was written with it. Very nice.
I'm trying to learn what you did to write Pacman, but my graphics library will be entirely vector-based, so no more of those yucky antialiased jagged textures, and made especially for SVGA. I'm doing this for my own optical engine, then onto the FI and POST for my homemade operating system Chiplock, and then for what's known as a GCLI, which is just a regular CLI with graphical elements included to create a sense of immersion. It would have also been handy if CRT monitors were still common.
That was awesome! I remember doing this in the early 80's. I have a lot of nostalgia for this and sometimes actually miss it, if you can believe that! More please!
Happy memories of designing a tiny antialiased font to draw text in 256 color SuperVGA. It was for a simple GUI to acquire and show CCD camera data for use in an electrophysiology lab (looking at calcium transients in cells using calcium-sensitive fluorescent dye). Somehow there was enough room on the screen to display the image frame, a histogram and a control panel at the same time. The advantage of whatever mode I used was it had square pixels (so the image frame wasn't distorted) and there were enough colors to represent the range of intensity values coming in from the camera. If I remember right, it was a variable width font with maximum width 6 pixels and a height of 9 pixels. The manual 'antialiasing' was two-tone.
Ah brings back memories getting into assembly on my 6502 atari 800 xl back in 1981 or something... Still up till this day, 40 years later one of the most satisfying periods in my life :P
This is amazing! It also shows up how in previous a programmer have to think twice before using a single byte otherwise they may run out of volatile memory. The code was clean and explanation wad on point. Really great work!
Great video!! I never have to touch low-level programming in my line of work but as time goes on in deepening my appreciation for this technology and the people who both understand it and are willing to share it. Everything is built on top of this! Incredible!
Hi Dave, thanks for the great video! This takes me back to my C64 days. You're absolutely right about the bit pattern for the characters being right to left on a left to right ordered screen memory. Though I never even gave it a second thought at the time, it just made sense since it was writing a byte to memory and that's the order of the bits for a 6502/6510
Yes, I remember my first challenger in programming when I was teenager and was to create a line function, no internet, no books. Then next challenger was a painting function, seriously very complex for me and more easy was to create a draw circle or ellipse function, only play with sines and cosines.
I'm learning Spring Boot and Java, a real programming language as many people say, not like JavaScript. I found out Java was based on C. So many things worked thanks to C, it's incredible. I also just found out your channel, it looks very interesting. Keep it up. 👏👏👏
3:22 *Correction:* 128 is the first left pixel. 127 would be the right 7 pixels of the first 8 pixels. The Apple 2 reverses the bits for HGR. LSB is left-most bit, MSB is a palette bit, and bit 6 is the right-most pixel.
Idk how to do it from scratch but There are functions for that in the windows library. GetAsyncKeyState will capture keys(even when the program is minimized).
@@bobfarker4001 Well it doesn't matter if the program is minimized unless you have focus checks or you wait event. Peek event or no window / draw loop at all will just make the program work in the background. I made a little keylogger like that, forgot about it for awhile and checked the file later only to see me trash talking people in tf2.
@@puppergump4117 LOL. it is funny when you look at your own logs. I've made several keyloggers, some email some save locally. If you're email that is doing the logging gets hacked you're fucked.
Thanks Dave, it really is quite nice to receive a master lesson on such simple graphics outputs. Reminds me of learning Fortran over a night shift so that I could modify a shift trivia quiz to include a graphical image, using ascii characters. Amazing what you learn when you need it! Writing Trev wins with an image of a winners cup, no matter who wins, was the result I famously added to the code! Take that A-shift! Hahaha 🤣
Hi. Great video. Every video I've ever seen you make is a great video. I wrote a line-draw algorithm using Bresnahan's algorithm, which is faster than the most modern line-drawing algorithm. I used system functions to draw text. I might rewrite that to make the text code more portable. At 3:22, you said the 127 was for the leftmost pixel and 1 was the rightmost pixel. I think you meant 128 and 1, unless the pixel is set to zero, in which case a mask of 127 is correct for the left-most pixel, and a mask of 254 is needed for the rightmost pixel. I'm sure you know what, and that most people realized what you meant.
I used to love creating my own character graphics on bbc basic. I’d have loads of 8x8 graph paper doodles then calculate the byte for each line. I was 8.
It's cool because I always knew how font code in terminals technically works and probably could write it myself but its just cool to see it. I never really knew where that code actually exists in Linux whether it's a library function or something in BASH. It's such a basic thing to draw ascii it just feels like one of those things that's so rudimentary yet important that i don't even know where to find it
That reminds me of the first games I tried to make in high school. Going from amiga to a PC, playing with power basic and int 13h screen modes. How you could swap between 2 screen buffers to not see the screen flicker during updates. It was cool how drawing triangles, and fill routines worked. Reading code from dr.dobbs journal in asm.
I'm glad that i took hard copy of my gfx library back in mid 90's. After HDD crash it would have been gone otherwise. "beautiful" C and assembler code in actual paper made by bit over twenty years old Airjuri. :D It has filled polygon, bresenham line, -circle and some screen fading effects. Off course all optimized for 320x200 screen. I should probably finish that game project i started back then ;)
I started using C for direct screen graphics in the DOS days using interrupt 10 to set VESA video modes. There day I still enjoy writing directly to the screen using C++ and the frame buffer and more recently drm/kms on Linux.
I am a big fan of your channel. Not much of a programmer, I hope you can one day start an x86 assembly tutorial for some of us who learn best by watching. It would be nice to see some practical x86 tutorials and its relevance to old hardware. I have some books but theory is not the same as practical.
Dave, would you be willing to do a programming series? I'm talking about all programming languages, from the ground up, at least the basics. I need that, and I'd bet others do too. You explain things better than most.
Hi dave, I made my own petscii font (C64) in python with hex codes in a list. I used it for the LED Matrix TEXT scroller I built from a leftover 2812b strip. It was fun to do.
It is not porting. CC65 just generate 6502 code from C. You need to set a configuration to target KIM-1 - it is pretty much the extra stuff you need (beside the actual code) to make it easier/useable by the system.
Hey Dave, Very cool! Love the KIM-1 drawing some cool stuff. Some ideas for next videos: - Since you now have the Commodore start screen, implement BASIC 🙂 - Let it draw the Mandelbrot set 🙂 - Port a C64 game to the KIM-1. Probably an "easy" one, without sprites... OR, implement you own game... e.g. Tetris 🙂 Keep up the cool videos, especially about Commodore stuff and the KIM-1. Greetings from Germany, Nils
It would be interesting to see how LLVM-MOS compares to CC65 these days. There are some rather large projects using LLVM-MOS now, including CP/M for the 6502.
Would love to see you make a program or game for the Commander x16. I've programmed C for 3-4 years, and I struggled to grasp this from the first second. If that is basic, I bow to your skills.
Loved it... Just the episode for "weirdos" like me that think doing stuff like a console graphics library, console raycasting renderers and the like is "fun". A graphics "first principles" of sorts. If i may suggest, add a text renderer that won't wrap and only draws whatever is within the valid screen area. Scrolling text, floating text, moving text in general. Guess FloodFill is next :P
Actually, adding another comment has become my trade mark. So I would add that we should explore the layers of programming onions to see if we can create a screen function, similar to screen 1,1; or screen 2 altering the mode to graphics mode, just like the PET. Be interested to see if you could add this to the simple graphics card in some fashion! 😊
Will we ever see a new Tempest bath robe record run again? Loved the last record video and the atmosphere where you had a casual morning with your coffee and setting a new record. Highly enjoyed watching it during my morning routine as well. :)
This reminds me times when I was seven years old with zx spectrum at home, some programs in basic and one book to look at and to learn from. For some reason my mother which knew something about programming (algol, prolog ,fortran ... not sure) from university helped me with writing programs drawing doilies. I guess it was some cycloids with use of trigonometric functions. But I'm sure basic had sin, cos, putpixel or similar command. It was nice to watch cause it took some time. I'm surprised that computer from that era has C.
@@stevetodd7383ops. Yes. Editor in 80s didn't have syntax highlighter and I was not thinking about cross compiler. Which brings question how to transfer data. USB to serial? Old computer with floppy drive? Audio cable emulating tape?
@@pavelperina7629 I think Dave mentioned connecting via serial. These machines did lack a lot of the oompf needed for a modern IDE, and even at the time a lot of commercial work was cross compiled on mini computers (MS BASIC started life on a PDP IIRC).
Thank you Pal!!!! ESPECIALLY Thank you for Windows 95b OSR2 - my first "my" PC my dad bought me was a 133MHz Pentium w/MMX inside Packard Bell, i wish i still had it. I remember finding out that the Right-Mouse button did stuff 0.0 and then as i explore every little piece i could, i would check out the About... and find your name many times. before that my computers were the tandy color computer line, i remember creating my own operating system/client-user-interface/data-decoding-REencoder using an interfacer with my coco3 and two half height floppy drives. course at the time i didnt know any of those words, i was just trying to create a master program i could have perform multiple computation tasks while i was at school and then review the results on disk when i got home from time to time. but i was like 12 or something, soo... You though, you totally rock man!!! I love your videos and show them to people i know in my local area including a friend a few days about about your book, he told me he's going to check it out. and for the on-topic subject: yes i love your videos, every chance i get some free time, im checking them out. i especially love your style of C/C++ which is gnarly awesome!! I am in the process of working on my own (is it 'retro' the kids calling it these days??) anywho, my own 'computer' of sorts from scratch. I am hopeful i can get something that i can eventually mass produce and sell but we'll see
I once had to do something similar in TRS-80 basic to render a working analog clock. The "pixel" drawing was quite interesting in that machine since the character set contained 64 characters consisting of 2x3 black&white (black&green) blocks (one character for each possible combination of those 6 "pixels"). The way of walking a line to draw each pixel was pretty much the same as in your case, Dave. The "mathematics" (missing most of the C bit manipulation options) of setting/clearing specific pixels was a bit of brain teaser though. And needles to say that it was slow enough to make a real-time seconds hand unthinkable. On the other hand, clearing/filling the screen (when done in machine code) was fast enough to create a stroboscope thanks to the mere 1K of video memory and the mighty handy LDIR or LDDR instructions (those of you with any Z80 experience can probably code that in under a minute). Anyway, thanks for an entertaining trip back in time to those early times where problems had to be solved by pure brain-power rather than processor-power. :)
Man, it's been many decades since I've seen code this far down in the weeds, but I do remember the good old bit flipping days of C/ASM. Thanks for refreshing those brain (RAM) cells... should be good for another 30 years or I get unplugged.
Hi, Dave. nice c video. do you have some videos about your IDE and plugins/extensions you used in the video? nice piece eye catching is the mouse-over tooltip showing variables/functions call info. that's nice to have
Takes me wayyyy back to the 80s/90s when I was teaching myself graphics programming. Turned out it was a passing phase and sysadmin/programming then database work was where my future lay, but fun nonetheless.
This is definitely fascinating writing runnable programs for the PET in C. Some quick questions about it, is this being cross-compiled eg. like on x86-x64 platform with the toolchain targeting whatever instruction set the PET uses? Is there anything like a notion of an executable format on the PET? eg. PE32 on windows, ELF on Linux. How do you load the compiled executable onto the PET?
He mentioned CC65 which is a C cross compiler for the 6502 CPU. The CC65 compiler can generate multiple output formats, like raw images of machine code or even a PRG-file for the C64 etc. I have a few videos on my channel about the CC65 compiler. I'm not anywhere Daves level though. :)
Good stuff. There is a DirectBitmap class on stack overflow that'll give you C# for drawing pixels at speed in winforms using a pinned memory array. What graphics functions could leverage parallelized linq? That's probably an unexplored niche.
Could you explain the algorithm behind "brasin' ham"? How often do I need to baste the ham? Kids in the Hall has alerted me to such ham-related issues like "Saltly Ham" and of course the "Ham of Truth"
I did almost the same thing about 20 years ago on an 80286 PC. As I remember very clear about the address 0xa000. It is the begining address of 13h VGA mode, which is a 320 x 200 screen. After Microsoft Windows 95, you can't draw graphics by writing data to screen memory.
With SVGA graphics, the SetPixel function must obviously be tweaked for what colour the pixel should be; obviously an int type will do, but care must be taken to ensure the proper ordering of alpha, blue, green, and red channels. And now I also know how my own homebrew library, for rendering NURBS contours, should be written.
Hi Dave … would you consider to create an Assembler and C-Language Beginner tutorial series? I know there are a lot of tutorials here on YT, but not in that type of quality 👌🏻
I'm doing the same thing today, on MCU ;p (started on Apple 2 in 81, 8Bits, Official Atari dev, Next, BeOS, Mac, PC, Dreamcast, GC, Wii, PSP, PS2 3 4 5, Xbox etc.. And now back to the roots on MCU, and back to 2D, Threads, Memory, Filesystem, bootstrap and void main(void) ;p
Very nice. Always interesting to see how tasks like this get done with different languages. I'm currently working on a collaboration for a game engine written in Windows Batch. It's amazing what the language is capable of when you know how to use it to full effect.
Brings back happy memories of coding on a DOS box and having to implement all of that functionality myself. How quickly could it render to a screen buffer and then flip it to the display? Or is there not enough main memory for a buffer?
If you were lucky then the video RAM didn’t suffer contention with the CPU (you’d see visible glitches on screen when both tried to access it at once. The PET tried to restrict it’s self to video updates during the blanking period because of this). RAM was far to expensive to waste for a double buffer.
Does the setpixel also has a starting point and ending point where the pixel draw is starting from and ending on? to make it possible to calculate from each side where to perform a future possible draw call within some future functionality. This could be useful for determining light sources on surfaces and what not for 2D or 3D games.
I would love to see this on each of the current major platforms too, because this is how I started coding on every machine: Apple II, TRS-80 Model 1, ZX Spectrum, Amiga, DOS & older Windows. Usually first in the native BASIC and then moving to machine code, assembly, C, C++. But on modern Windows, Mac, Linux (and maybe the phone OSes) I would love to do the same, but man it's hard to impossible to find some example or tutorial like: - Use the "native" language of the device/OS: C, C++, C#, Swift, Kotlin - Don't use any frameworks or libraries or SDKs other than the most basic ones the OS comes with or its official community/free dev tools come with - Use the lowest level supported techniques of the device/OS - Open a window, or preferably a screen or a full-screen borderless window - Be able to draw either by some equivalent lowest level graphics primitives equivalent to plot() and line() - OR to have access to bitmap memory where I'd need to implement my own plot() and line() primitives - Handle window resizing, screen resolution changes, etc (in other words no hardcoded window dimensions) I realize most and probably all systems now go through a 3D pipeline even for 2D graphics and may not offer any direct way to the native hardware bitmap since that belongs to the graphics card. But a full and thorough discussion of this would be one of the major parts of the basic intro at the start. Then old fart programmers could have fun like the old days on their fast new systems! Someone start a git repo (-:
Honestly search engines nowadays are disappointing it's just full of garbage i guess the only way to find information is through books, videos like this one or just simply asking chatgpt
@@yuyuyuyuyuy484 Programming books are disappearing and getting horribly expensive. I thought they were horribly expensive 30 years ago (-: There's very few people doing videos on this kind of thing. There are some for retro systems. More using frameworks of many kinds. A couple using text console are good though! Community is best if I'm not the only one looking for this. This is something I haven't thrown at codebots yet though. Time to try...
@@andrewdunbar828 I'm assuming these kind of videos are few because youngins (like me) don't need to understand such low level concepts because a lot of us want to do stuff quick, nevertheless its very interesting to learn about; have fun with the codebots lol.
@@yuyuyuyuyuy484 Definitely! I like the videos for the youngins and the ones by the youngins as well as the ones by and for us olduns (-: So far the codebot has been trying valiantly but I'm starting with macOS which is the least documented so it's going around in circles but in different circles to the ones I go in when I try to work it all out myself...
This is fascinating. How cool would it be if Dave were to design a full Commodore 64-esqe operating system for this that could emulate basic (or even JIT compile basic when it's run) and make this a fully usable computer like a commodore pet/64/whatever?
I'm wondering if you have enough memory on that thing to implement the full libc. If so I'd love to see it. As for the table, I'd use one regardless of how many or few edge cases there are because it'll always be faster and 256 bytes is really not too much to ask in this instance. If we were talking about upper and lower casing things, then it might be too much.
@@willynebula6193 EDK2 repo is a way to go, it is always good to study from code, you will learn to drive basic input / output on a board level. If you like to read story-like books, can't miss Beyond BIOS.
@@Gilvin wow thank you, UEFI development was not quite what i had in mind. I was thinking along the lines of the old school pc bios. However im definitely going to check out the UEFI info. Thanks mate
was always looking for something like this. I am learning to design graphic library for embedded displays. Do you know any books where I can learn more on this topic about ??
And you will never look back, once you get your head around it, you will wonder why didn't you learn it years Ago. It really is amazing what you can do with it. Good luck
Please, more on anything cc65. It’s such a cool tool and a pity the project’s face to the world are a neglected website (edit: TWO websites?!), and an old-fashioned email list. CC65 so old school, the documentation is SGML!
Really neat stuff. Not as low level but I remember doing the turtle graphics in Pascal. There was a lot of advanced stuff with assembly I found from a really talented Dutch programmer I had befriended at that time that did really remarkable stuff with animation and fonts and all sorts of stuff I wish I kept. I’m sure it’s on a random 3½” floppy in a box at my parents house that if exists probably wouldn’t work it is virus-laden.
@@AlwaysCensored-xp1be that’s pretty cool. I think Pascal was my first ‘real’ as in compiled language after learning BASIC in the MS-DOS days and I was amazed in how much better it was to work in. I later switched to C/C++ and pretty much stayed. I’d love though to find my old pascal stuff and play with it again.
Your fluency with bit-shifting and boolean is mesmerizing; a master-class video from you would be solid gold.
That idea may be logic but i don't think he has the skills to be a good teacher. Just because we know something that doesn't makes us smart to teach it.
That's really very basic stuff. Bit tricks go a lot further than this in the real world, it's a heap of fun! Just as an exercise for you: try to think of a way to swap two variables without using a temporary variable, but by just using bit operations. Or have a look at a fast bitcount, etc.
This brings back a lot of memories. It was like 2000 or 2001 and I was learning C using books and a compiler written in the 80s! (Borland Turbo C/C++ 1.1) I still have a great sense of nostalgia for that blue background with chunky yellow text and seeing functions written in that glorious font with pointers that poke and peek directly into memory and occasionally prodding hardware registers brings back some fond memories. Thanks , Dave!
Wow, that was really close to when I was doing the same thing, except I found DJGPP, the GNU 32bit DOS compiler, which was used to make Quake as well. Definitely brings back memories for me as well! Loved coding my own graphics like this, and the GNU compiler made it so much easier as you didn't have to worry about things like long jumps, memory boundaries etc... DJGPP handled all that for you.
@@NeilRoy Ha, yeah! I discovered DJGPP a year or so later. It really opened up a lot of options since I was no longer limited to a measly 640k of RAM. Though I think it came at the cost of operating in protected mode which meant you couldn't quite access memory with the same directness as before.
same but the 90s!
TurboC! i remember using it from 1.0 up to a german 3.7 version!
Get off my lawn. This takes me back to 1981.
Greetings from San Francisco. I thought there were no time machines, but you just brought me back to 1979. I loved it the first time around, and I'm (almost) ready to break out my Poly88 with a Cromemco Dazzler and write code along with you. Almost... but sanity prevailed. Dave, you are a BAD influence. I can't wait for your next stroll through my faded youth.
I remember implementing the Bresenham circle algorithm in assembly and also figuring out the math behind it when I was in 8th or 9th grade where I had just learnt the the Pythagorean theorem. It was so awesome :)
You can speed up that Bresenham's implementation considerably by avoiding calls to SETPIXEL. Instead, translate the x,y starting point to a byte address and a mask (as done within SETPIXEL), and within the loop, treat x moves as shifts of that mask (adding/subtracting one to the byte offset if the mask becomes 0), and treat y moves as adjustments (add/subtract BYTESPERROW) of the byte address.
Back in the day (circa 1985 with an EGA/VGA adapter on a PC running MS-DOS) I had an assembly language Bresenham's that was nearly as fast as a NEC 7220 based board.
Also, for a lot of applications (I was doing CAD work at the time), it is well worth the minimal effort to optimize horizontal and vertical lines.
Back on my CGA machine I was doing just that. I started with a setpixel (ASM inside of C code). That was about 200x faster than the built in command..
I started with this level of simple line command, setting every pixel of the line. Then improved it with a look at how many bits in a byte are set and did them all at once.
Fun times!!
@@hrayz Yeah, BGI, Borland's graphics library, was useless. It was nice and compatible, but useless in terms of speed. And couldn't access MCGA / 256-colour mode. Better to just set a big pointer to graphics RAM and do it yourself.
More C programming please. Love it!
This reminds me so much of when I was a kid programming different early machines that did not have any built in graphics like the early Atari and TRS80. I love it, please make more videos like this one. Thank you very much.
A few years ago I wrote a graphics primitive library for Arduino driving a 20*10RGB led array. This was used in a series of digital art workshops as part of our National Arts Festival. The best of the art was later displayed on our huge Rgb periodic table display. Each element was about 6x6” . Since the pixels were wired in an odd order I created a translation table to translate x/y to pixel number. Fun times.
I love the fact that you are probably going to be the only human on this planet running this code, but you still have sanity checks to ensure that you're not going outside of screen memory. The force of habit from a person who has had to reflexively sanitize inputs his entire life.
Loved this! Man, this takes me back. I still prefer to program in C (not C++) to this day, usually using a GNU compiler which supports the newer versions of C. I remember programming graphics in DOS on my old computer in the 1990s. I wrote my own graphics library much like you have here by accessing A000 etc... as I learned I added more functions to it for lines, some optimized functions for straight lines (I think that used memset commands to set larger amounts at once). I loved those days and the fact that it wasn't done for you. I created a free game called Deluxe Pacman 1 & 2 for DOS, older Windows and modern Windows (last tested on Windows 10) and it is coded entirely using C (no plusses), only it uses the Allegro library (I honestly wish I had done it entirely on my own and never used a library). Good times anyhow.
Oh, and I used to use DJGPP for DOS back then, it handled the memory limitations for you, so no worries about things like long jumps and the like. I believe Quake was written with it. Very nice.
This is so cool. I always wonder how did you guys learn these things, I really love low level programming but I don't understand it that much.
I'm trying to learn what you did to write Pacman, but my graphics library will be entirely vector-based, so no more of those yucky antialiased jagged textures, and made especially for SVGA. I'm doing this for my own optical engine, then onto the FI and POST for my homemade operating system Chiplock, and then for what's known as a GCLI, which is just a regular CLI with graphical elements included to create a sense of immersion. It would have also been handy if CRT monitors were still common.
That was awesome! I remember doing this in the early 80's. I have a lot of nostalgia for this and sometimes actually miss it, if you can believe that! More please!
I'm surprised how simple this code looks, despite the fact that it's so low-level. Very interesting!
Happy memories of designing a tiny antialiased font to draw text in 256 color SuperVGA. It was for a simple GUI to acquire and show CCD camera data for use in an electrophysiology lab (looking at calcium transients in cells using calcium-sensitive fluorescent dye). Somehow there was enough room on the screen to display the image frame, a histogram and a control panel at the same time. The advantage of whatever mode I used was it had square pixels (so the image frame wasn't distorted) and there were enough colors to represent the range of intensity values coming in from the camera. If I remember right, it was a variable width font with maximum width 6 pixels and a height of 9 pixels. The manual 'antialiasing' was two-tone.
Ah brings back memories getting into assembly on my 6502 atari 800 xl back in 1981 or something... Still up till this day, 40 years later one of the most satisfying periods in my life :P
Taking in stuff that's over your head is the first step to raising your head so time well spent.
This is amazing! It also shows up how in previous a programmer have to think twice before using a single byte otherwise they may run out of volatile memory. The code was clean and explanation wad on point. Really great work!
Why you don't say ram instead of volatile memory? Anyway agreed
This C stuff is so great to watch it was a simpler time, but at the same time more complicated (?)
I’m a beginner but still so interested in low level programming. This is amazing! I feel like C is such an awesome first language
Great video!!
I never have to touch low-level programming in my line of work but as time goes on in deepening my appreciation for this technology and the people who both understand it and are willing to share it. Everything is built on top of this! Incredible!
As someone with little programming knowledge this video is really good.
Hi Dave, thanks for the great video!
This takes me back to my C64 days. You're absolutely right about the bit pattern for the characters being right to left on a left to right ordered screen memory. Though I never even gave it a second thought at the time, it just made sense since it was writing a byte to memory and that's the order of the bits for a 6502/6510
Great video, it's always great to take a stroll through low level land and look under the hood. We take a lot of modern libraries for granted!
Yes, I remember my first challenger in programming when I was teenager and was to create a line function, no internet, no books. Then next challenger was a painting function, seriously very complex for me and more easy was to create a draw circle or ellipse function, only play with sines and cosines.
That display is beautiful. I love old graphics
This is great. I recently wrote my own graphics API using similar algorithms. I will have to add Moire! Thank you for your channel.
I'm learning Spring Boot and Java, a real programming language as many people say, not like JavaScript. I found out Java was based on C. So many things worked thanks to C, it's incredible. I also just found out your channel, it looks very interesting. Keep it up. 👏👏👏
You're my hero 💙 and all I have been looking for.
Finally now I have a tutorial guide for the idea behind how graphics were designed and implemented.
3:22 *Correction:* 128 is the first left pixel. 127 would be the right 7 pixels of the first 8 pixels.
The Apple 2 reverses the bits for HGR. LSB is left-most bit, MSB is a palette bit, and bit 6 is the right-most pixel.
True, thanks!
That takes me back to programming on a VGA in assembler. I remember wishing I could do it in C.
I’ll absolutely take more of this. I’d like to see code for capturing mouse and keyboard input.
Idk how to do it from scratch but There are functions for that in the windows library. GetAsyncKeyState will capture keys(even when the program is minimized).
@@bobfarker4001 Well it doesn't matter if the program is minimized unless you have focus checks or you wait event. Peek event or no window / draw loop at all will just make the program work in the background. I made a little keylogger like that, forgot about it for awhile and checked the file later only to see me trash talking people in tf2.
@@puppergump4117 LOL. it is funny when you look at your own logs. I've made several keyloggers, some email some save locally. If you're email that is doing the logging gets hacked you're fucked.
Thanks Dave, it really is quite nice to receive a master lesson on such simple graphics outputs. Reminds me of learning Fortran over a night shift so that I could modify a shift trivia quiz to include a graphical image, using ascii characters. Amazing what you learn when you need it! Writing Trev wins with an image of a winners cup, no matter who wins, was the result I famously added to the code! Take that A-shift! Hahaha 🤣
Hi. Great video. Every video I've ever seen you make is a great video.
I wrote a line-draw algorithm using Bresnahan's algorithm, which is faster than the most modern line-drawing algorithm. I used system functions to draw text. I might rewrite that to make the text code more portable.
At 3:22, you said the 127 was for the leftmost pixel and 1 was the rightmost pixel. I think you meant 128 and 1, unless the pixel is set to zero, in which case a mask of 127 is correct for the left-most pixel, and a mask of 254 is needed for the rightmost pixel. I'm sure you know what, and that most people realized what you meant.
Dave, enjoy your podcast. Would like to see you interview the folks who made up the team that created the 6502.
I would be interested in this as well!
I used to love creating my own character graphics on bbc basic. I’d have loads of 8x8 graph paper doodles then calculate the byte for each line. I was 8.
Assembler gets my vote :)
Thank you, Dave!
It's cool because I always knew how font code in terminals technically works and probably could write it myself but its just cool to see it. I never really knew where that code actually exists in Linux whether it's a library function or something in BASH. It's such a basic thing to draw ascii it just feels like one of those things that's so rudimentary yet important that i don't even know where to find it
Excellent. Please continue professor...
That reminds me of the first games I tried to make in high school. Going from amiga to a PC, playing with power basic and int 13h screen modes. How you could swap between 2 screen buffers to not see the screen flicker during updates. It was cool how drawing triangles, and fill routines worked. Reading code from dr.dobbs journal in asm.
Dave, this was super-cool! Thank you so much for posting this video. Yes, would love to see more content like this. Cheers!
I'm glad that i took hard copy of my gfx library back in mid 90's. After HDD crash it would have been gone otherwise. "beautiful" C and assembler code in actual paper made by bit over twenty years old Airjuri. :D
It has filled polygon, bresenham line, -circle and some screen fading effects. Off course all optimized for 320x200 screen. I should probably finish that game project i started back then ;)
I gave this a thumbs up before I even skipped past the ad that preceded it
Edit; And after watching, I wasn't wrong.
I started using C for direct screen graphics in the DOS days using interrupt 10 to set VESA video modes. There day I still enjoy writing directly to the screen using C++ and the frame buffer and more recently drm/kms on Linux.
I am a big fan of your channel. Not much of a programmer, I hope you can one day start an x86 assembly tutorial for some of us who learn best by watching. It would be nice to see some practical x86 tutorials and its relevance to old hardware. I have some books but theory is not the same as practical.
It brings me back to the good old days when the bar was low regarding customer expectations, and it was easy to impress people. Even yourself.
Really enjoyed this one. I am somewhat in the middle of working out how to render text to the C64 bitmap display, so this was a handy video.
Dave, would you be willing to do a programming series? I'm talking about all programming languages, from the ground up, at least the basics. I need that, and I'd bet others do too. You explain things better than most.
Hi dave, I made my own petscii font (C64) in python with hex codes in a list. I used it for the LED Matrix TEXT scroller I built from a leftover 2812b strip. It was fun to do.
I remember doing this kind of programming for the PC before windows came out. Sound drivers too… fun times. Blew up a monitor or two.
Thank you sir. You are a living library.
FINALLY
someone who gets my goals c:
Nice idea of porting a C compiler, even if limited, to the KIM-1. Good stuff.
@Dm_official_Daves_Garage BOT! All, do not reply to the fake Dave!
It is not porting. CC65 just generate 6502 code from C. You need to set a configuration to target KIM-1 - it is pretty much the extra stuff you need (beside the actual code) to make it easier/useable by the system.
Hey Dave,
Very cool! Love the KIM-1 drawing some cool stuff.
Some ideas for next videos:
- Since you now have the Commodore start screen, implement BASIC 🙂
- Let it draw the Mandelbrot set 🙂
- Port a C64 game to the KIM-1. Probably an "easy" one, without sprites... OR, implement you own game... e.g. Tetris 🙂
Keep up the cool videos, especially about Commodore stuff and the KIM-1.
Greetings from Germany,
Nils
It would be interesting to see how LLVM-MOS compares to CC65 these days. There are some rather large projects using LLVM-MOS now, including CP/M for the 6502.
You could save 256+ bytes from result just rearranging of font array. And even save some ticks of CPU. Precalculatable things should be precalculated.
excellent, expect more things like this, thank you
Would love to see you make a program or game for the Commander x16. I've programmed C for 3-4 years, and I struggled to grasp this from the first second. If that is basic, I bow to your skills.
Please make MORE of videos like this.
Loved it... Just the episode for "weirdos" like me that think doing stuff like a console graphics library, console raycasting renderers and the like is "fun". A graphics "first principles" of sorts. If i may suggest, add a text renderer that won't wrap and only draws whatever is within the valid screen area. Scrolling text, floating text, moving text in general. Guess FloodFill is next :P
Sounds like the beginning of a C only/CPU only 3d renderer from scratch series :)
I’ve always had this misunderstanding of how to use bit shifting and utilizing bitwise operands, a video on that would be very nice !
Could you show how cpu instructions set implement to programing language and vice versa?
You're very talented. This video is great
I think I would have needed 3x more lines. Great job.
Why not reorder the ramfont instead of using translation tables for finding the right index?
Love you explanations, so easy to understand.
Thanks for the memories.
Actually, adding another comment has become my trade mark. So I would add that we should explore the layers of programming onions to see if we can create a screen function, similar to screen 1,1; or screen 2 altering the mode to graphics mode, just like the PET. Be interested to see if you could add this to the simple graphics card in some fashion! 😊
Will we ever see a new Tempest bath robe record run again? Loved the last record video and the atmosphere where you had a casual morning with your coffee and setting a new record. Highly enjoyed watching it during my morning routine as well. :)
Nice tutorial short & to the point.
Mode 0x13
Oh this bring back the good ole tutorials
When a grid misaligns with one that's behind, that's a Moire!
You forgot the "🎵"!
This reminds me times when I was seven years old with zx spectrum at home, some programs in basic and one book to look at and to learn from. For some reason my mother which knew something about programming (algol, prolog ,fortran ... not sure) from university helped me with writing programs drawing doilies. I guess it was some cycloids with use of trigonometric functions. But I'm sure basic had sin, cos, putpixel or similar command. It was nice to watch cause it took some time.
I'm surprised that computer from that era has C.
That's a great memory, Pavel.
It’s a modern C compiler that targets 6502 code. C was far from popular on that generation of hardware at the time.
@@stevetodd7383ops. Yes. Editor in 80s didn't have syntax highlighter and I was not thinking about cross compiler. Which brings question how to transfer data. USB to serial? Old computer with floppy drive? Audio cable emulating tape?
@@pavelperina7629 I think Dave mentioned connecting via serial. These machines did lack a lot of the oompf needed for a modern IDE, and even at the time a lot of commercial work was cross compiled on mini computers (MS BASIC started life on a PDP IIRC).
Thank you Pal!!!! ESPECIALLY Thank you for Windows 95b OSR2 - my first "my" PC my dad bought me was a 133MHz Pentium w/MMX inside Packard Bell, i wish i still had it. I remember finding out that the Right-Mouse button did stuff 0.0 and then as i explore every little piece i could, i would check out the About... and find your name many times.
before that my computers were the tandy color computer line, i remember creating my own operating system/client-user-interface/data-decoding-REencoder using an interfacer with my coco3 and two half height floppy drives. course at the time i didnt know any of those words, i was just trying to create a master program i could have perform multiple computation tasks while i was at school and then review the results on disk when i got home from time to time. but i was like 12 or something, soo...
You though, you totally rock man!!! I love your videos and show them to people i know in my local area including a friend a few days about about your book, he told me he's going to check it out.
and for the on-topic subject: yes i love your videos, every chance i get some free time, im checking them out. i especially love your style of C/C++ which is gnarly awesome!! I am in the process of working on my own (is it 'retro' the kids calling it these days??) anywho, my own 'computer' of sorts from scratch. I am hopeful i can get something that i can eventually mass produce and sell but we'll see
ohh i meant to say yes I would like to see more videos on programming graphics in C/C++ and on your computer research! +1
I once had to do something similar in TRS-80 basic to render a working analog clock. The "pixel" drawing was quite interesting in that machine since the character set contained 64 characters consisting of 2x3 black&white (black&green) blocks (one character for each possible combination of those 6 "pixels"). The way of walking a line to draw each pixel was pretty much the same as in your case, Dave. The "mathematics" (missing most of the C bit manipulation options) of setting/clearing specific pixels was a bit of brain teaser though. And needles to say that it was slow enough to make a real-time seconds hand unthinkable.
On the other hand, clearing/filling the screen (when done in machine code) was fast enough to create a stroboscope thanks to the mere 1K of video memory and the mighty handy LDIR or LDDR instructions (those of you with any Z80 experience can probably code that in under a minute).
Anyway, thanks for an entertaining trip back in time to those early times where problems had to be solved by pure brain-power rather than processor-power. :)
Sixel graphics.
Man, it's been many decades since I've seen code this far down in the weeds, but I do remember the good old bit flipping days of C/ASM. Thanks for refreshing those brain (RAM) cells... should be good for another 30 years or I get unplugged.
Hi, Dave. nice c video. do you have some videos about your IDE and plugins/extensions you used in the video? nice piece eye catching is the mouse-over tooltip showing variables/functions call info. that's nice to have
Takes me wayyyy back to the 80s/90s when I was teaching myself graphics programming. Turned out it was a passing phase and sysadmin/programming then database work was where my future lay, but fun nonetheless.
This is definitely fascinating writing runnable programs for the PET in C. Some quick questions about it, is this being cross-compiled eg. like on x86-x64 platform with the toolchain targeting whatever instruction set the PET uses? Is there anything like a notion of an executable format on the PET? eg. PE32 on windows, ELF on Linux. How do you load the compiled executable onto the PET?
He mentioned CC65 which is a C cross compiler for the 6502 CPU. The CC65 compiler can generate multiple output formats, like raw images of machine code or even a PRG-file for the C64 etc. I have a few videos on my channel about the CC65 compiler. I'm not anywhere Daves level though. :)
Good stuff. There is a DirectBitmap class on stack overflow that'll give you C# for drawing pixels at speed in winforms using a pinned memory array. What graphics functions could leverage parallelized linq? That's probably an unexplored niche.
Could also use xxd -i to generate the font array.
Could you explain the algorithm behind "brasin' ham"? How often do I need to baste the ham? Kids in the Hall has alerted me to such ham-related issues like "Saltly Ham" and of course the "Ham of Truth"
I did almost the same thing about 20 years ago on an 80286 PC. As I remember very clear about the address 0xa000. It is the begining address of 13h VGA mode, which is a 320 x 200 screen. After Microsoft Windows 95, you can't draw graphics by writing data to screen memory.
With SVGA graphics, the SetPixel function must obviously be tweaked for what colour the pixel should be; obviously an int type will do, but care must be taken to ensure the proper ordering of alpha, blue, green, and red channels.
And now I also know how my own homebrew library, for rendering NURBS contours, should be written.
Hi Dave … would you consider to create an Assembler and C-Language Beginner tutorial series? I know there are a lot of tutorials here on YT, but not in that type of quality 👌🏻
If you think that in 8 min you will learn C/ASM ... then yes, there are no tutorials "in that type of quality" :D
I'm doing the same thing today, on MCU ;p (started on Apple 2 in 81, 8Bits, Official Atari dev, Next, BeOS, Mac, PC, Dreamcast, GC, Wii, PSP, PS2 3 4 5, Xbox etc.. And now back to the roots on MCU, and back to 2D, Threads, Memory, Filesystem, bootstrap and void main(void) ;p
Really great. thanks for the insight.
Very nice. Always interesting to see how tasks like this get done with different languages. I'm currently working on a collaboration for a game engine written in Windows Batch. It's amazing what the language is capable of when you know how to use it to full effect.
old robocop is amazing Sir
Brings back happy memories of coding on a DOS box and having to implement all of that functionality myself. How quickly could it render to a screen buffer and then flip it to the display? Or is there not enough main memory for a buffer?
nooo buffers there...
If you were lucky then the video RAM didn’t suffer contention with the CPU (you’d see visible glitches on screen when both tried to access it at once. The PET tried to restrict it’s self to video updates during the blanking period because of this). RAM was far to expensive to waste for a double buffer.
Does the setpixel also has a starting point and ending point where the pixel draw is starting from and ending on? to make it possible to calculate from each side where to perform a future possible draw call within some future functionality. This could be useful for determining light sources on surfaces and what not for 2D or 3D games.
Awesome explained
I would love to see this on each of the current major platforms too, because this is how I started coding on every machine: Apple II, TRS-80 Model 1, ZX Spectrum, Amiga, DOS & older Windows. Usually first in the native BASIC and then moving to machine code, assembly, C, C++.
But on modern Windows, Mac, Linux (and maybe the phone OSes) I would love to do the same, but man it's hard to impossible to find some example or tutorial like:
- Use the "native" language of the device/OS: C, C++, C#, Swift, Kotlin
- Don't use any frameworks or libraries or SDKs other than the most basic ones the OS comes with or its official community/free dev tools come with
- Use the lowest level supported techniques of the device/OS
- Open a window, or preferably a screen or a full-screen borderless window
- Be able to draw either by some equivalent lowest level graphics primitives equivalent to plot() and line()
- OR to have access to bitmap memory where I'd need to implement my own plot() and line() primitives
- Handle window resizing, screen resolution changes, etc (in other words no hardcoded window dimensions)
I realize most and probably all systems now go through a 3D pipeline even for 2D graphics and may not offer any direct way to the native hardware bitmap since that belongs to the graphics card. But a full and thorough discussion of this would be one of the major parts of the basic intro at the start.
Then old fart programmers could have fun like the old days on their fast new systems!
Someone start a git repo (-:
Honestly search engines nowadays are disappointing it's just full of garbage i guess the only way to find information is through books, videos like this one or just simply asking chatgpt
@@yuyuyuyuyuy484 Programming books are disappearing and getting horribly expensive. I thought they were horribly expensive 30 years ago (-:
There's very few people doing videos on this kind of thing. There are some for retro systems. More using frameworks of many kinds. A couple using text console are good though! Community is best if I'm not the only one looking for this.
This is something I haven't thrown at codebots yet though. Time to try...
@@andrewdunbar828 I'm assuming these kind of videos are few because youngins (like me) don't need to understand such low level concepts because a lot of us want to do stuff quick, nevertheless its very interesting to learn about; have fun with the codebots lol.
@@yuyuyuyuyuy484 Definitely! I like the videos for the youngins and the ones by the youngins as well as the ones by and for us olduns (-:
So far the codebot has been trying valiantly but I'm starting with macOS which is the least documented so it's going around in circles but in different circles to the ones I go in when I try to work it all out myself...
This is fascinating. How cool would it be if Dave were to design a full Commodore 64-esqe operating system for this that could emulate basic (or even JIT compile basic when it's run) and make this a fully usable computer like a commodore pet/64/whatever?
I'm wondering if you have enough memory on that thing to implement the full libc. If so I'd love to see it. As for the table, I'd use one regardless of how many or few edge cases there are because it'll always be faster and 256 bytes is really not too much to ask in this instance. If we were talking about upper and lower casing things, then it might be too much.
Bring almost bare-bone to live never tires me, that's why I became a BIOS engineer, so much fun.
Im interested in this exact topic. What would you recommend for somebody wanting to learn how to write and understand the code at the bios level?
@@willynebula6193 EDK2 repo is a way to go, it is always good to study from code, you will learn to drive basic input / output on a board level. If you like to read story-like books, can't miss Beyond BIOS.
@@Gilvin wow thank you, UEFI development was not quite what i had in mind. I was thinking along the lines of the old school pc bios. However im definitely going to check out the UEFI info. Thanks mate
This is so beautiful
was always looking for something like this.
I am learning to design graphic library for embedded displays. Do you know any books where I can learn more on this topic about ??
Hey I just started learning C yesterday!
Good Luck 🙂
Have fun! 🙂
And you will never look back, once you get your head around it, you will wonder why didn't you learn it years Ago. It really is amazing what you can do with it. Good luck
Congratulations! This, from a Bell Labs C-language applications software developer circa 1979.
Please, more on anything cc65. It’s such a cool tool and a pity the project’s face to the world are a neglected website (edit: TWO websites?!), and an old-fashioned email list.
CC65 so old school, the documentation is SGML!
Really neat stuff. Not as low level but I remember doing the turtle graphics in Pascal. There was a lot of advanced stuff with assembly I found from a really talented Dutch programmer I had befriended at that time that did really remarkable stuff with animation and fonts and all sorts of stuff I wish I kept. I’m sure it’s on a random 3½” floppy in a box at my parents house that if exists probably wouldn’t work it is virus-laden.
Free Pascal is still alive and I use Ultibo bare metal version on Raspberry Pi.
@@AlwaysCensored-xp1be that’s pretty cool. I think Pascal was my first ‘real’ as in compiled language after learning BASIC in the MS-DOS days and I was amazed in how much better it was to work in. I later switched to C/C++ and pretty much stayed. I’d love though to find my old pascal stuff and play with it again.