Jump to content

R0ger

Members
  • Content Count

    753
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by R0ger

  1. It does brighten it up .. it also kills the colors. The skewed gamma might be from the source image, I pushed it (and saturation) in the source image. There is for sure tons of tweaks you can do on the source.
  2. Actually I did encountered that already, and non-LMS line already have extra CLC.
  3. I tried .. but I simply can't squeeze another poke in there. The timing is too tight. After the last PMG is moved, I have to load 3 registers so they can be used right after wsync. I'd like try to remake the kernel to be aligned perfectly with CPU so there would be no need for wsync. Then there could be just enough time for it.
  4. That's how you report error ! Thanks man ! I will release convertor and source images soon.
  5. No. That way you will have 2 half-pixels cover the same area. It would increase color-space, but not resolution. This trick doubles horizontal resolution, while keeping color depth. On both C64 and Atari.
  6. I've been fiddling with this for some time, unable to solve the problems it has. So I will leave it here, at least we can talk about it. First, the idea is not mine. It's based on C64 demo AlgoDream by Algorithm. I got to know him because of his (and mine) works on Bad Apple, and we had some juicy chats since then. So all credits goes to him, I only adapted the idea for the Atari. So what is the idea ? Horizontal interlace ! You mask one half of the low-res pixel in one frame with PMG (which is black) .. and then you mask other half of the low-res pixel in the next frame. That allows you to have two different colors on space of 1 low-res pixel. You can even use checkerboard pattern on the mask to improve the look. On C64 that means you can have 320 pixels resolution with colors of 160 pixels mode. C64 has high-res PMG, and you can cover the whole width of the screen with them. See here: https://youtu.be/HtRxD5Zkanw?t=9m27s Atari has only 160 low-res PMG. But then it has super-low-res GTIA modes with many colors, and it can work the same. But there is another problem. If you used what we call hi-res PMG (160px), you wouldn't be able to cover the whole screen. But then you can position PMG using 160px coordinates, even if PMG is wider. So you can use low-res PMG (80px), but shift it so left half of PMG pixel masks right half of one underlying pixel, while the right half of the PMG pixel masks left half of next underlying pixel. The masking pattern is a bit different, but as long as you only see one half of the pixel in one frame and another in next frame, it works. With wider PMG, and some tough kernel code, I was able to cover almost whole screen - 144 pixels of the 160. I also combined it with common 9/11 interleaved mode, which gives me 144x100 pixels with 256 colors. Before you hop to the sample .. read about the problems it has, and why it's not the new hot thing: - it's full, independent, color mode. It takes lot of memory, basically twice as much as the usual. 16k. - it needs full screen kernel. - since the masking is done by overlaying the pixel with black PMG, each pixel is black half of the time. On the average, it means half brightness of the resulting apparent image. Pls. note that some better TVs will adjust and expand the brightness automatically, mitigating this problem almost completely. - it flickers. Well, that's the idea, right ? - LCD displays. Do you know how PAL interlace actually use half line offset for odd and even fields ? Well Atari doesn't do that. No 8bit does (AFAIK). They simply generate odd frame again and again. So the lnes overlap exactly in individual frames. That's NEEDED for this method. CRTs and TVs can display it just fine. Most LCD can't. They are too smart. They have full frame memory, and they process the signal to combine two fields to reconstruct full non-interlaced frame. And these days they don't bother with basically illegal PAL signal. They ASSUME there are odd and even fields, and they will do the half-line shift regardless. So they take my 2 checkerboard fields, shift one of them half line down, then they merge it into one, perfectly static image. It looks terrible. For your own sake, do not try this on LCD. You've been warned. - Emulators. It doesn't work properly even on emulators ! Not that it uses any specific hardware trick, which would be unimplemented. But most of the time, you run emulator on 60Hz monitor, and that doesn't translate well to 50Hz PAL interlace mode. Let's talk Altirra, because that's what I use. Worst case it will flicker terribly at about 10Hz differential frequency. To avoid flickering completely, use 'Frame blending' in video options. You get super-smooth, stable, godly .. but unrealistic result. Another simple option is to change video to NTSC. The palette will shift a bit, but the interlace rate will match your PC monitor, and it looks almost as on real CRT. 50Hz flicker and 60Hz flicker look almost the same. Yet another option is to leave video on PAL, and change overall emulator speed to exactly 120%. And of course, if your monitor can handle 50Hz mode, that's the best. Also don't forget to turn PAL artifacting to at least low, otherwise modes 9 and 11 won't mix properly and you will get washed out colors ! - Visible grid. Another problem, which mostly affects real CRTs, is that there is very thin grid visible over the image. Thing is, the pixels on CRT are not perfectly sharp. They are more like fuzzy balls. If you flicker checkerboard pattern, and average it over time, the pixels will not perfectly connect. It's visible even in emulator, if you do not use frame blending, and if you for example bilinear resize mode. It's hard to catch on screenshot, but if you encounter it, you will know. - I don't have name for it. Algorithm calls it something like sprite-mask-hires .. but on Atari we call sprites PMG, and it's not exactly hires Anyway .. enough stalling .. here it is (picture and xex): Girl.xex
  7. BTW. I just noticed .. the filtering on lead voice in Reharden demo is somewhat good. Doesn't sound like normal RMT filter .. any tricks to it ?
  8. I tried to modify my test project, which used 16kHz IRQ source, to 64kHz, and indeed, with reset Done in DLI, I can sync it even at 4kHz. Char mode + DLI, no visible conflict. The sample playback is not as clean as 64kHz, but it's still quite clean. And it means I still have 3 channels to do whatever I want ! Still sample playback is both memory and time hungry, not sure I will use it in the end (it's like a puzzle game, secret, obviously). And btw. I actually used the same channel for IRQ source and output already I was thinking about trying some full softsynth for Atari .. but using it only for bass is great idea. And you could also try sampled drums, as they don't need high sample rates.
  9. Sorry if I sound uninformed, I'm kinda new to Atari, and all my experience with this is one attempt to make sample playback. I understand all your explanation about synchronization. Still .. you say you use 1 channel for both IRQ source AND synth output ? And one channel only ? Didn't think you can do that. I can and will check the source codes, but maybe you can explain a bit here ? How exactly do you setup the channels ?
  10. I'm loving it ! Still few things I don't understand. Mainly 64kHz source. You say you are realigning the IRQ every frame .. is it enough to prevent IRQ/DLI conflict ? Well since it's once per 8 lines, I guess it is, but I want to know more. Also the demo is stereo pokey right ? I mean you need 2 channels for IRQ, and even if you share synth with RMT, the music is clearly more then 2 channels .. right ? Thanks for making everything public !
  11. Somebody halp ! I'm going mad. I'm quite sure it is (was ?) possible to set scanline brightness in Altirra. I mean brightness of the space between scanlines if you enable 'scanlines' in system/video. I have videos recorded from Altirra where the space between scanlines is pure black. But now it's like 50% of the scanline. Or did it simply change ?
  12. Haha we were talking with Fandal what game to convert from C16/C64 platform whole Bytefest (2 weeks back). This one was not mentioned. But then I think he would mention it if he were working on it at that time. Does it mean he made the conversion in 2 weeks !?
  13. Division is not that big of a problem imho .. true, for your 1 pixel per line you will need 8.8 division (only 0.8 for normal line) .. but you can look at such division as 16 pixel long Bresenham line, not even that. That puts things into perspective.
  14. Any line can be drawn left to right .. so you will never have negative delta X. That's how you can do it with just 8 bits. And for up and down, you have 2 variants, and again, each variant only works with positive delta Y.
  15. Well typically you always draw from left to right, you just swap the coordinates when they come in the wrong order. And then you have 2 variants of the life for up and down .. so you never have one code handling 2 directions.
  16. Btw. kinda relevant and very good video on Elite, by big B. himself .. http://www.gdcvault.com/play/1014628/Classic-Game-Postmortem Together with this thread I again can't sleep and I transform and draw lines in my head all the time. Braben mentions several interesting tricks: 1) using logarithms for everything. I've tried, but IMHO it's only useful for 8bit camera space. I use 16bit, and that kinda throws it out of the window. I'm still thinking about some interpolation, which would convert log and exp into 1 8x8 multiplication, but so far I haven't been successful. Also Braben doesn't mention fast mul we use today, with this method the logs might not be that good. 2) symmetry - now this is no brainer, it will work in most engines. Simply transform every vertex also as it's mirror image. It's very cheap, and most of them will be used in the model, as models tends to be symmetric. I think it could be optimized by having the symmetric vertices first in the vertex array, and then doing the symmetry only for first N vertices. Or even hove some vertex symmetric side by side, and some symmetric side by side AND up and down. Gonna implement it into my engine for sure. 3) recreating transformation matrices - sin tables or normalization, both is somewhat costly. Elite doesn't do it every frame. It uses static matrix additions to do small predefined rotations, and the loss of precision is accepted. Only after several such operation the matrix is re-normalized. Might be useful in many cases. Maybe not for camera matrix, but surely for object matrices. He also talks about line a bit, but not in much detail .. still it seems in lot like articles on codebase64, which I never understood .. but now I might be actually on how it works. But I will implement it first. I think it's gonna be faster and shorter then my current tree method. Also I came up with new division method for my engine. I use 16/16 division, but I only need 8 bits of result. Also in the engine the result is always less then 1. At the moment I scroll the 16bit operands up, till all the bits are used - in other words I'm scratching the leading zeros .. and then I do 8/8 division, the classical way. I tried to make some kind of table to avoid the classical division .. and now I've been finally successful ! Let's say we divide A/B. As I said, result is always <1 .. so A<B. So when I'm scratching the leading zeros, B always ends up with 1 in the top bit. Before last 8 bit division, B is always in range 128-256. That's significant simplification, as it's inversion (in this case 256/x) can go from only from 2 to 1. Still not very good for table. But if I subtract 1, I get range 1..0 .. or 255 to 0. Let's call this number Q. Now to get the division, I have to do A*(1+Q) .. which is same as A+A*Q .. which is simple. It gets my division from average of 251 cycles to 130 cycles, and I think there is still lot of room of improvement by low level optimization (for example at the moment I call the mul simply by jsr). On the global it lowers time consumption of division from 5% to under 3%, at the price of 128 bytes table (well that and huge scroll tables, but I have them anyway). There are some bugs in the clipping I still have to solve, but do far it looks good !
  17. I know people who have the source codes personally. Thing is they were quite reluctant in giving them away. I guess it would depend on what you plan to do with it. For example I have so many issues with RMT that no simple modification would solve it .. I want completely new software. But I don't have time for that
  18. Here is my routine .. but clearly I remember it wrong .. I use the tree even for steep variants. The steep variant still does draw from both ends, but you will have to get through it all .. good luck .. I think it's the most cryptic code I produced in my life. Rough orientation in the code .. line.asm is normal Bressenham, nothing fancy there. You want line2.asm. Line3.asm is just UP variant of Line2, you can ignore that. First there are some macros. DrawByte is output macro for the shallow variants - it draw byte aligned patterns. DrawPatternDown and DrawPatternUp are used in steep variants .. the Bressenham tree is basically the same for steep and shallow variants, but the final macro is what's different. DrawPatternDown and DrawPatternUp draw pixel the usual way, and it's in these macros where you can see drawing using 2 pointers and two masks, ie. from both ends. The line itself has the usual coord swapping and variant decision .. and then come the trees .. labels starting with L1 are the shallow version, L2 is the steep version. Labels like L1_100x are levels of the decision tree .. this example means decision were 1-0-0 and 4th decision is unknown yet. After the decision tree there is the drawing block .. for example L1_5 is for decisions 0-1-0-1 .. it's just decimal representation .. please note that each drawing block is used twice .. as the first decision only says if you should move down before the whole block .. so block for 0-0-0-0 overlaps with 1-0-0-0, and so on. There is also some code to handle special cases - ends in shallow variant and middle of the line in the steep variant .. but honestly I don't understand it at all at the moment. Still it works LineTest.zip
  19. That alternating segment length variant ? Forget it .. you would have to divide for each line ..
  20. Btw. there is still one idea I keep thinking about .. if you take the segments of the line, you are always alternating only 2 segment lengths .. and the length varies by 1. For example you alternate between 2 pixel segments and 3 pixel segments. Bressenham can be easily modified to decide between these 2 variants, instead of simple right or right-up. It could be very fast, especially if you could prepare specific variants of the routine for most common slopes. Or maybe have routine which would have unrolled code for let's say 20 pixels, and for shorter segments you will modify the addresses of the jumps. It doesn't take byte alignment into account, and you would need register for the mask, but then you can take it as advantage .. it would work the same with any pixels per byte mode.
  21. Check here: http://atariage.com/forums/topic/231690-known-fast-line-algorithms/ Drawing from both ends for sure helps a lot, while having the code still quite flexible and clean. At the moment it's my favorite method. In my vector demo I use what I call 'tree Bressenham' .. It's only for shallow variants (0-45 degrees), and it works like this: Bressenham basically decides if you do right only, or right and up. If you have 4 pixels per byte, this gives 16 variants per one byte worth of width. You can look at it as binary tree, 4 levels deep, with Bressenham decision at every node, and with 16 leaves, where the code outputs the bytes directly. For example if the tests in leaves were right-right-right-right .. the code in the leaf just writes $ff and it's done. Thing is you don't need register for mask, it's all in the code itself. Very fast. But also very long, and you can't easily change colors, or drawing operation (OR, XOR), by modifying code. For the steep variants I use the both-ends approach. In the thread above there is even faster method mentioned .. it uses decimal deltas, and at every step id draw 4 pixels. It basically has 4 screen pointers, for 0,25,50,and 75% of the line, and every decision is used 4 times. But the lines are not so pretty, and they often have jaggies on the 25,50 and 75%, as the ends don't align properly .. this algorithm is also not very exact, it would not hit the target point if it was used for whole screen width. But 160 resolution is quite low, and I wanted red-magenta 3D, so I wanted lines as correct as possible, that's why I didn't go this way.
  22. I do clipping in 3D, because I have to .. I can have line starting in front of the camera, and ending behind the camera. So making persp first and clipping later just doesn't work. You could probably clip with some kind of 'near plane' ..parallel to screen plane .. and then do 2D, but still it seems prone to overflows to me. But then you can control the world and camera, so you the problematic cases might never happen.
  23. It has some minor issues .. especially that superscaling of objects I was talking about - 3D doesn't take that into account just yet. But you will most likely not notice it the way I do. Anyway .. I made a video .. here it is: Please don't post it anywhere, it's work in progress.
  24. Yeah, sry, I don't go here very often .. PG notified me about this thread though .. I do clipping in 3D, before persp .. basically clip the edges with view frustum. I use 90 degrees horizontal view angle .. so it's just comparing X to Z .. and for vertical I use half of that .. so I double each coordinate after rotation, and then half it back before drawing, and again, just compare Y to Z. Each edge is then clipped against 4 planes (I plan to add fifth 'near plane' because of some glitches) .. new vertex is computed, the formula something like (a-b)/(c-d) .. so there is division. But you don't need full 3D coordinates, as one coordinate of the final 2D projected point is derived from the plane, you are clipping with. Like if you are clipping with right border (X=Z plane), it's clear that the X coordinate on the screen will be .. right border ! So you only have to get Y and Z of the clipped point, then do persp, to get projected Y. My objects can't rly be in infinity .. there is limit to 16 bits of camera space. But I have some tricks .. I can subscale or superscale object by power of two. The matrix itself is still 8 bit, and contains just the rotation .. but then I scale the relative position of the object by the power of two .. using scroll tables .. which makes the object appear bigger or smaller, with no precision lost, and with no precision cost. I plan to cram whole star systems into 16 bit camera space, you simply use different coordinate systems for planets, and different for ships, and so on .. As for stars in the demo, they are what I call 'no position' object .. it's placed right on the camera, without translation, so no mater how camera moves, they still stay on the same spot in camera space, so they look like they are in infinity. The screenplay system for the demo can add objects, set their speed and rotation, camera can move too, and it can 'watch' specific object. There are some tricks for the sake of the demo, like manual object culling, and the scale tricks, but generally it relies on the engine itself .. if you would want to look at the scene from different point, you would just change camera coordinates.
×
×
  • Create New...