|
Forum Index : Microcontroller and PC projects : Doing a FizzleFade
| Author | Message | ||||
| karjo238 Regular Member Joined: 12/10/2018 Location: New ZealandPosts: 60 |
Hello! I'm writing a game, and for the game over screen would like to do a fizzle fade, as described here: https://jacopretorius.net/2017/09/wolfeinstein-3d-fizzlefade-algorithm.html It's the Game Over screen for Castle Wolfenstein (as you may have guessed ), and I really do like it.After some searching, I found a version of the fade that looked easy to convert into MMBasic, which was the code at http://antirez.com/news/113. This was Javascript, so I went ahead and converted it into MMBasic 5.0.3, and I ended up with this: screen_width = MM.HRes screen_height = MM.VRes frame = 0 Function feistelNet(in) r = in >> 8 For i = 0 To 7 nl = r F = (((r * 11) + (r >> 5) + 7 * 127) Xor r) And &hff r = l Xor F l = nl Next i feistelNet = ((r<<8) Or l) And &hffff End Function Sub putPixel If frame = 1677216 Then End fn = feistelNet(frame) x = fn Mod screen_width y = Fix(fn / screen_width) If x < screen_width And y < screen_height Then Pixel x,y,RGB(red) EndIf frame = frame + 1 End Sub Do While 1=1 putPixel Loop It sort of works. I mean sort of because it goes across 640 pixels, but only down about 100 pixels. As far as I can tell, I have done everything right, and their is a link to the working code on the page. Can anybody who is wiser than me spot anything silly I might have done? This sort of stuff is a bit beyond me, and I'm certain there's some element I'm not grasping properly. Any help would be gratefully appreciated. Joseph |
||||
| JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 4135 |
It may be the line If frame = 1677216 Then End I suspect you mean Return instead of End. John |
||||
| CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 2171 |
I think you mean END SUB - you RETURN from a GOSUB, not a SUB - But... Any SUB should only have a single corresponding END SUB. If you want to bail early, you EXIT SUB. However, I believe the poster really wants to end his program (due to the While 1=1) so there is a fundamental change needed to signal to the loop. Perhaps turning the SUB into a FUNCTION that returns a zero until the required test is true . this way the DO could test this and finish when all pixels have been done... something like Function putPixel() as Integer putPixel=0 If frame = 1677216 Then putPixel=1:Exit Function fn = feistelNet(frame) x = fn Mod screen_width y = Fix(fn / screen_width) If x < screen_width And y < screen_height Then Pixel x,y,RGB(red) EndIf frame = frame + 1 End Function ... Do Loop Until putPixel()=1 Even this is not ideal. due to the parameter passing there will be a slow down (tiny) of the code - I would do the whole fade in a single SUB personally... depends if you want to do other stuff while it is fading. Sub putPixel for frame=0 to 1677216 fn = feistelNet(frame) x = fn Mod screen_width y = Fix(fn / screen_width) If x < screen_width And y < screen_height Then Pixel x,y,RGB(red) EndIf next End Sub which dispenses with the do:loop completely and should be a lot faster because you don't call the SUB for each faded pixel. Further acceleration could be gained from taking the guts of the feistelNet function and putting it in the putPixel sub (if it is only called from here why not?) and then eliminate the If x... If y... tests by calculating values that are guaranteed to fall within range without the need for testing. this may not be what the OP wants though. |
||||
| JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 4135 |
I see I meant EXIT SUB not Return. We need to hear back from the OP. John |
||||
| karjo238 Regular Member Joined: 12/10/2018 Location: New ZealandPosts: 60 |
Hey there, sorry about the delay in replying. After rereading the antirez.com page again, I realised that this effect is only valid for resolutions up to about 320x200, and would require something completely different for numbers above that, so this was a bit of a dead end Many thanks for the help anyhow. Joseph. |
||||
| AussieWombat Newbie Joined: 04/05/2018 Location: AustraliaPosts: 21 |
Hi Joseph, i had a look at the javascript, and amended the code so that it works for a multiple of 320 x 200. Just set the canvas size to 640 x 400, even did 960 x 600. the page works out the number of bits to move etc. So I hard-fixed your code hopefully. You had left out 1 line. screen_width = MM.HRes screen_height = MM.VRes frame = 0 total = 2 ^ 18 Function feistelNet(in) l = in And &h1ff r = in >> 9 For i = 0 To 8 nl = r F = (((r * 11) + (r >> 5) + 7 * 127) Xor r) And &h1ff r = l Xor F l = nl Next i feistelNet = ((r<<9) Or l) And &h3ffff End Function Sub putPixel If frame = total Then End fn = feistelNet(frame) x = fn Mod screen_width y = Fix(fn / screen_width) If x < screen_width And y < screen_height Then Pixel x,y,RGB(red) EndIf frame = frame + 1 End Sub Do While 1=1 putPixel Loop try that and see how you go. Need to peruse the javascript, I can arrange that. |
||||
| karjo238 Regular Member Joined: 12/10/2018 Location: New ZealandPosts: 60 |
I'll do just that! This sort of coding is a bit beyond me, and I posted here in the hopes that someone cleverer than I had a solution. Many, many thanks! |
||||
| karjo238 Regular Member Joined: 12/10/2018 Location: New ZealandPosts: 60 |
Alright, I've tested it, and it did what I thought it might - it just took too long. I have a Micromite Extreme 144, but to fill the screen took too much time for the purposes I had in mind. What I decided to do instead is go the other way and fill the screen with 4x4 boxes so the screen effectively has a resolution of 160x120, and this works quite well. I just have one small problem to solve, and that is the BOX command in MMBasic 5. If I put in something like: BOX x*4,y*4,4,4,0,RGB(red),1 MMBasic complains that 16711680 (the numeric value of red) is not a suitable number. I'm using the VGA output, not any sort of LCD screen. What do I need to put in to make a red box appear on the screen? I tried adding COLOUR RGB(red) at the start of the code, but it made no difference. I'm sure it's something silly, but I can't immediately fathom it.... Many thanks, Joseph |
||||
| AussieWombat Newbie Joined: 04/05/2018 Location: AustraliaPosts: 21 |
I think with the BOX command follows the format of X1 = x*4 Y1 = y*4 width = 4 height = 4 so far so good LW (Line weight) = 0 Hmm don't want any line border. still ok C = RGB(red) This is the colour to draw the non existent border. FILL = 1 Probably the problem, should be a colour value. So try RGB(red) to fill the square with red. ie: BOX x*4,y*4,4,4,0,RGB(red),RGB(red) Cheers Dennis |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10572 |
Just checked your command on a MMX and not getting any error so something else must be going on. However, as Dennis says your command is drawing a box with a zero-width red outline (i.e. nothing) filled in the colour "1" which is basically black |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |