Jump to content

stepho

Members
  • Posts

    172
  • Joined

  • Last visited

Everything posted by stepho

  1. Agree that over commenting is a waste. Disagree on the other points. The closer it looks like line noise then the more likely there will be a typo that the eye will gloss over and that the compiler happily accept. I'll take verbose but obviously correct code any day over short but potentially wrong code. You are in a maze of twisty syntax that all look the same.
  2. I always mentor my junior colleagues to not do that in their C/C++ code. It leads to the next guy thinking that c=1 is also conditional when it isn't. Of course, when trying to bum every byte then you do what you need to do - but it's still gross.
  3. Try: 45 Y=25-Y:X=X+80: REM MAKE X AND Y POSITIVE TO FIT SCREEN 50 PLOT X,Y Should give the same results for one less calculation.
  4. Using different words: If there is something in the code that is very easy to break, then it should be documented in the code itself - ie right next to the part that breaks easily. I've lost count of the number of times that the previous programmer just "knew" that certain things had to be done or not done. But the knowledge wasn't passed on to me and I broke things that needlessly took me ages to find out why. When I eventually fixed them I put a comment in the code about why something had to be done in a certain way. Thinking ahead for the next guy to modify the code is what separates the hackers from the professionals.
  5. Always document caveats. Otherwise someone will modify it later and it will crash for an unfathomable reason.
  6. For the few games that don't work on real hardware, you still have the option of using an emulator. Maybe a different experience than real hardware but at least you can play the games.
  7. My own experience (35 years embedded) is similar. Get the algorithm right (eg, an O(n) search routine is not as good as an O(log(n)) search routine). Beware of C++ habits where the values get transparently translated back and forth with each layer. Eg, object A stores a figure as a int. Object B wants that figure as a string - luckily object A has a interface that translates it to a string. Object C wants that figure from B (with operations done to it) but wants it as a float - luckily object B has a interface that translates it to a float. Object D wants that figure from C (with operations done to it) but wants it as a int - luckily object C has a interface that translates it to a int. More time spent on wasteful conversions instead of the actual operations. Write the code with an eye towards the platform. Saw a colleague write an 8-bit AVR program using 32-bit signed ints throughout. Changed it to 8-bit unsigned ints and it was dramatically smaller and faster. But do not optimise it to death so that it is unreadable and unmaintainable until after the critical parts are identified by a profiler. Replacing code like x*8 with x<<3 is just making life hard for the maintenance programmer. Modern compilers usually do this far better and lets you leave the code far cleaner. Leave these "tricks" in the 80's where they belong unless timing is super critical or your compiler is old.
  8. I would modify that slightly - do hand optimisations only when they are needed. The compiler should be free to do automatic optimisations whenever possible. Although some hints from the author can change which optimisations the compiler can choose from. Eg, in C, the volatile keyword on a variable disallows a pile of optimisations but allows the variable to read from a hardware location. Some other hints from the author also tell the compiler to optimise for speed or size - usually as a global option via command line flags. This reflects a basic tenant of mine - let the machine do the work.
  9. Thanks. I still don't understand but at least I'm in good company. Perhaps it's something to do with how fast the TIA can change the signal level or how fast a typical TV can follow the change. After all, TV's are designed for continuous tone images rather than sharp edges. Cleverly exploited though.
  10. ok, but I still don't know what's happening. Can you go into more details.
  11. This is new to me. I can see that the pics have wall steps of 4 dots and sometimes 1 of those dots is turned off to make the vertical black lines. Can you explain (or point to an explanation) how this works? Thanks.
  12. From work I have done on other embedded devices (not Atari), you can double the amplitude of the output waveform and it will not sound like double the volume to our ears. That's because the device is using linear values but our ears work on logarithm values. Most TV's with digital volume also suffer from this (ie volume 10% sounds okay but to double the perceived volume you need to go way up to 30% or more) For my device (which only needs simple buzzer-like sounds at various, fixed, frequencies), I set the amplitude according to the crude formula: amplitude = (vol^2)/100 where: volume is the desired volume 0..100 % amplitude is the amplitude of the output waveform 0..100 % Not truly logarithmic but parabolic is close enough. With this, the user can double the desired volume value and the perceived sound also appears to double.
  13. Both look good. I suspect the buggy version is due to round off errors due to the trig functions not being evenly spaced. Eg, sin(1)-sin(0) is a lot larger than sin(90)-sin(89) where 90 degrees is a right angle, not radians. I worked through the original algorithm and the maths is fine - assuming infinite precision. I tried to think of other variations but none were as fast (theoretically) as yours.
  14. For Total Commander, I found I had to enable passive mode in the FTP connection settings. Haven't used FTP for years, so not sure if it makes any difference today.
  15. Rodney Zaks "Programming the 6502", courtesy of the Internet Archive. https://archive.org/details/Programming_the_6502_OCR Zaks "programming the Z80" was my second book for learning assembler back in the day (PDP-11 assembly handbook was the first).
  16. Sorry, by motion blur I meant that for the fall back position (ie no repeated frame was found) of just grabbing the last X frames and then blending/averaging them, then anything that moved would show up in both old and new positions. Like the red box in your last image. The system would do it's best to look for repeated frame(s). If it can't find repetitions then it just takes the last 10 frames (or whatever number you deem best). Manual splicing is always an option - we just try to let the computer do as much of the work as possible. My day job is designing automated equipment that can go for months in the field without human intervention. So I naturally try to make it as self sufficient as possible. I hadn't thought of showing phosphor fading in the final static image. If you took multiple snapshots then there is no guaranteeing the same first frame in each snapshot - which means the fading could be different for each snapshot. But it might be a nice option in the GIF. Each final frame in the GIF would contain a weighted average from the other frames - with special care taken so the first few frames contain faded info from the last few frames. I have a few thoughts on how to do that but I'll wait a bit in case I've gone an option too far.
  17. It's nice that it is possible to get an image but requiring the user to slice and dice it by hand kind of goes against the whole idea of having computers in the first place. Whenever a human is doing work for the computer, then something is wrong. A key point that I mentioned above is for the tool to watch for recurring frames. If it sees frames like ABABABABABA (ie a 2 frame kernel) then it grabs A, grabs B, grabs another A, notices that the 3rd frame is identical to the first and then blends the first 2 frames. But this doesn't capture flickering stuff like ABACABACABAC and could miss the C frame. So we look for 2 consecutive frames. It grabs A, grabs B, grabs A (no AB match yet), grabs C (no AB match yet), grabs A (no AB match yet), grabs B, notices that last 2 frames match the first 2 frames and then blends the 4 frames (ie every frame minus the last 2 matching). If the player is moving around then it may take a few cycles before it finds a set that don't have movement. We are hoping that the game is not having things move at 50 or 60 times a second (or at least that it does so cyclically) otherwise no player could keep up with a screen that screams by in a flash. Fall back is that after say 10 frames it just blends all 10 and just accept some possible motion blur. The above could be coded with a single parameter n. n=1 means just look single frame identical to a previous frame. Handles AAAA, ABABABA, ABCABC, ABCDABCD type cases n=2 means looks for 2 identical frames in sequence., Handles ABACABACABAC type cases n=3 means look for 3 identical frames in sequence. Handles more complex cases but I can't think of examples. Might have trouble with motion blur.
  18. I'm curious about how you do the phosphor fade. Do you store n raw frames in a sliding window and then do a weighted average for the display? Or do you use a simple signal filter? eg: frame=getNewFrame(); frame = ( (oldFrame * k) + frame) / 2; // where 0<k<1 display( frame ); oldFrame = frame;
  19. Perhaps Gopher could capture frames until it finds a frame identical to one that it has captured before (with an upper limit of say 10 if the screens have objects that move around a lot). Then the user could choose to save that as either: a single frame formed by averaging all the frames an animated GIF showing each captured frame in turn, using the same timing as they were captured. Should work for ABABAB (captures AB), ABCABCABC (captures ABC), ABCDABCD (captures ABCD). Would still fail for ABCBABCB but do many games do that? If need, could make it stop when it sees 2 successive frames that are identical to 2 previous success frames. Ie, ABCBABCB would capture ABCB because AB was seen before.
  20. Any bits that are not explicitly defined should always be masked out. Otherwise you will find that some implementations will give %xx000001 but you may also find some other implications give other numbers. Or even the same hardware under different conditions (temperature, timing, previous operations). Never trust what isn't fully documented (and only partly trust what is documented ).
  21. It's not my code either but I can answer some of your questions. Most C compilers initialise variables to 0 (unless some other value is specifically given for a specific variable). So all the borders are initialised to have no border walls and are later modified to have bit 0 and/or 1 turned on via |= RIGHT or |=BOTTOM. Macro function can usually be converted to ordinary function in a mechanical fashion. static int GoodDir( int Cell, int Dir ) { return (g.Maze[Cell].Border & Dir) == 0; } Called by bool flag; flag = GoodDir( Cell, Dir );
  22. You are probably thinking of https://en.wikipedia.org/wiki/Bresenham's_line_algorithm
×
×
  • Create New...