Nop90 Posted January 4, 2020 Share Posted January 4, 2020 Today wanted to play a little with the HBL interrupt to display images with more than 16 fixed colors, so wrote a little script (using imagemagick) that from a generic 160x102 png first downscales the colors to 256, than creates a set of images (one for every line), everyone with only 16 colors. The 102 images are rendered on the screen and the corresponding platettes are changed at every HBL. Nothing new with this way to show more than 16 colors, only I'm not happy if I don't code things by myself. I was especting to have to apply some postprocessing to optimize the palettes, but surprisingly the images are very good only with the authomatic processing. Here are the first three image I converted. Attached there is the source code too. It's only a fast POC so forgive me the bad coding. I know that I don't need to use tgi to draw the image since I have to disable it to change colors and I also know that I don't need to use all that memory to setup data in memory but it's better to create offline two big arrays (one for image daa and one for the palettes), but I'm lazy ? What about it? I'm going to optimize this tool and use it to show nice colored splash screens in my next games. bigtree__colorpic.lnx nebula_colorpic.lnx skyline_colorpic.lnx hicol.zip 1 Quote Link to comment Share on other sites More sharing options...
sage Posted January 4, 2020 Share Posted January 4, 2020 (edited) will not work. if you use HBL interrupt you dont have the time to set the full palette. you either have to poll the register or set up another timer which interrupts before the end of line and then poll the register. Edited January 5, 2020 by sage Quote Link to comment Share on other sites More sharing options...
enthusi Posted January 4, 2020 Share Posted January 4, 2020 I described here how I did it for assembloids: The Bastion demo also features it including a scroller above the image. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted January 5, 2020 Author Share Posted January 5, 2020 I see, it only works on emulator, but not on real lynx, anyway it's a starting point for my experimenting. I'll try reducing the colors per line and optimixing the palette leaving some fixed colors. Do you yow how many clocks last the HBL for the 3 refresh rates? Quote Link to comment Share on other sites More sharing options...
Nop90 Posted January 5, 2020 Author Share Posted January 5, 2020 At 50hz my lynx 2 seems can do the job (try the attached rom), at 60Hz i can write only 29 bytes of the palette out of 32: at 30 bytes starts the flickering. So seems it's possible. Could soemone try it on a upgraded LCD? I have only unmoded lynx for the moment. skylyne_50hz.lnx Quote Link to comment Share on other sites More sharing options...
Nop90 Posted January 5, 2020 Author Share Posted January 5, 2020 The tree image looks great on my lynx tree_50Hz.lnx 1 Quote Link to comment Share on other sites More sharing options...
enthusi Posted January 5, 2020 Share Posted January 5, 2020 You can do it at 60Hz as well. I think HBL is not best suited since you lose the time you would otherwise have in Vblank. But it should work as well in HBL ? The tree is nice In general you'd want motives with vertical gradients to show off the colors. Quote Link to comment Share on other sites More sharing options...
sage Posted January 5, 2020 Share Posted January 5, 2020 1 hour ago, Nop90 said: I see, it only works on emulator, but not on real lynx, anyway it's a starting point for my experimenting. I'll try reducing the colors per line and optimixing the palette leaving some fixed colors. I think i left some code in the public version here. But I was not satisfied because i left too many relicts in the picture. http://lynxdev.atari.org/BmpConvert.exe Quote Link to comment Share on other sites More sharing options...
sage Posted January 5, 2020 Share Posted January 5, 2020 17 minutes ago, enthusi said: You can do it at 60Hz as well. I think HBL is not best suited since you lose the time you would otherwise have in Vblank. But it should work as well in HBL ? The tree is nice In general you'd want motives with vertical gradients to show off the colors. ONe question: how much is the music distorted if you use this? Quote Link to comment Share on other sites More sharing options...
enthusi Posted January 5, 2020 Share Posted January 5, 2020 You can check in Bastion ? In fact I didn't use 102 lines when music is running. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted February 9, 2020 Author Share Posted February 9, 2020 (edited) How many clock cycles is the horizontal blank (if any)? And the is the Vblank only the first 3 horizontal lines not displayed on the LCD? Edited February 13, 2020 by Nop90 Quote Link to comment Share on other sites More sharing options...
laoo Posted February 12, 2020 Share Posted February 12, 2020 (edited) @Nop90 I've tried to actually measure it by placing varying number of NOPs in the HBI routine. Please correct me if I'm wrong. First of all CPU clocks are no good unit of measure when dealing with tracing the beam as one clock cycle can take 4 or 5 system clock ticks. The whole line with 60 Hz refresh rate takes 159 μs = 2544 ticks. According to my measurements it seems that the first color change visible on screen is after about 30 μs = 480 ticks. It's slightly more than 100 CPU cycles. I'm attaching output of my test program. The white pattern is binary encoded VCOUNT_COUNT. Green pattern is a sequence of sta GREEN0 / stz GREEN0 delayed for about ( 26 + 80 + VCOUNT_COUNT ) * 4 + 11 * 5 system ticks including interrupt (+-4 ticks ). VBlank is for 3 lines, but keep in mind that two first visible lines are for some reason unstable just as if the HBI launched in various "moments" with few pixels of variance. Edited February 12, 2020 by laoo Quote Link to comment Share on other sites More sharing options...
laoo Posted February 12, 2020 Share Posted February 12, 2020 @Nop90 I forgot about the binaries. test.o Quote Link to comment Share on other sites More sharing options...
Nop90 Posted February 13, 2020 Author Share Posted February 13, 2020 thank you @laoo you helped me a lot. I was giving up in the project of displaying a general (i.e. not optimized at design time) 256 colors image on the screen of a real lynx. My code was working on the emulator but on real lynx I had problems in the first third of the screen. With your timing as reference I reorganized my code and now it works fine on real lynx. Here is an image (with attached the lnx rom if someone want test himself on a real lynx) of a nice splash screen that @marss made for 4ttude. I'm going to update the 4ttude rom with this tonight (I released a new version of 4ttude some hours ago, but without this splash sceen, because I was starting to think it was an impossible task to display it correctly). image.lnx 3 Quote Link to comment Share on other sites More sharing options...
laoo Posted February 13, 2020 Share Posted February 13, 2020 Nice. I'm attaching a snapshot from McWill-modded VGA output of real hardware: 2 Quote Link to comment Share on other sites More sharing options...
enthusi Posted February 14, 2020 Share Posted February 14, 2020 (edited) Nice. This mode has quite some potential in general! From the gfx used in the Bastion demo: Edited February 14, 2020 by enthusi 1 Quote Link to comment Share on other sites More sharing options...
Nop90 Posted February 14, 2020 Author Share Posted February 14, 2020 For the moment I want to keep my code private, but if someone wants I can give enough details on how I accomplished this to make it easily replicable. Obviusly the asm part can be decompiled from the rom, but there is a big part of automatic image preprocesssing done with perl scripts and the convert tool from imagemagick. Quote Link to comment Share on other sites More sharing options...
+karri Posted February 17, 2020 Share Posted February 17, 2020 This is truly exciting development! Good job! Quote Link to comment Share on other sites More sharing options...
Cyprian Posted February 17, 2020 Share Posted February 17, 2020 @Nop90 any details? change 16 colors every line? Quote Link to comment Share on other sites More sharing options...
Nop90 Posted February 17, 2020 Author Share Posted February 17, 2020 2 hours ago, Cyprian_K said: @Nop90 any details? change 16 colors every line? yes, the idea is simple, but timing is critical. I start from a 24 bit image, than at build time i call some perl scripts that uses the Imagemagick Convert tool to: - reduce the color to 256 - create a bmp3 (paletted) image 160x1 px for every line of the image, reducung for each the colors to 16 - read the data of the files of every single line line so to extract the pixel and palette data; and from this builds two data files, one is a standard unpacked lynx sprite, the other is an array with the 102 palette datas + 3 dummy palette rows (all zeroes) for the VBLANK (to simplify the HBL handling). Pixel and palettes data are reorganized so that colors are in (reversed ) oder of occurrence so that the first colors to be used are the first to be updated every scanline. The order is reversed because a loop using decrementig X register as a counter saves a CMP instuction every loop respect the case of X incrementing. To update the palette the code: - sets X to 16 - sets the G value of the color at X position in the X position of the G colors array - sets the RB value of the color at X position in the X position of the RB colors array - decrements X - if X is not 0, branches to the second point - before exiting the HBL handler updates the addresses to the palette pointers (at points 2 and 3) adding 32 to the LSB ofthe two addresses and if carry is set incrementing the MSB. That's all. After several tries, this code can display an image without flickering without the need to decide color utilization and order at designtime. Obviously such a general code produces some horizontal artifact, but the result isvery good. I tryed usinf 15 or 14 colors instead of 16 with good results. The two unused colors can be used to add other effects (text scrollig) and maybe to same some computational time. This is my next challenge. 1 Quote Link to comment Share on other sites More sharing options...
enthusi Posted February 17, 2020 Share Posted February 17, 2020 The one crucial optimisation you are missing is to set the colors in order of appearance. Then changing 16 colors is no problem at all. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted February 17, 2020 Author Share Posted February 17, 2020 (edited) 3 hours ago, enthusi said: The one crucial optimisation you are missing is to set the colors in order of appearance. Then changing 16 colors is no problem at all. No, I'm not missing it. 4 hours ago, Nop90 said: Pixel and palettes data are reorganized so that colors are in (reversed ) oder of occurrence so that the first colors to be used are the first to be updated every scanline I know my English is not very good with complex sentences. Sorry. Edited February 17, 2020 by Nop90 1 Quote Link to comment Share on other sites More sharing options...
enthusi Posted February 17, 2020 Share Posted February 17, 2020 Ah sorry, I misread that then. The Textscroller in Bastion uses 14 free colors and keeps 2 colors global Quote Link to comment Share on other sites More sharing options...
Cyprian Posted February 18, 2020 Share Posted February 18, 2020 (edited) @Nop90 nice idea. can you estimate how many cycles or % of scanline it takes on real hardware? Edited February 18, 2020 by Cyprian_K correction Quote Link to comment Share on other sites More sharing options...
Nop90 Posted February 18, 2020 Author Share Posted February 18, 2020 (edited) 1 hour ago, Cyprian_K said: @Nop90 nice idea. can you estimate how many cycles or % of scanline it takes on real hardware? I don't know how may cycles last the scanline, but is a simple thing to estimate knowing the screen frequency is set to 50 Hz (the timer 0 frequency is in the Lynx programming manual). The code execution time can be calclated from my code: setpal: hbl: pha phx lda INTSET and #TIMER0_INTERRUPT beq vbl sta INTRST ldx #15 ADR1: lda GCOLMAP,x ; dummy address. It's dinamically set in intInit and updated by vbl and hbl sta GCOLMAP,x ADR2: lda RBCOLMAP,x ; dummy address. It's dinamically set in intInit and updated by vbl and hbl sta RBCOLMAP,x dex bpl ADR1 clc lda ADR1+1 adc #32 sta ADR1+1 bcc incaddr2 inc ADR1+2 bra incaddr2 incaddr2: clc lda ADR2+1 adc #32 sta ADR2+1 bcc done inc ADR2+2 bra done Can my code be optimized to be faster? Let me know. Edited February 18, 2020 by Nop90 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.