It is the 1727th of March 2020 (aka the 21st of November 2024)
You are 18.219.18.238,
pleased to meet you!
mailto:blog-at-heyrick-dot-eu
A week in the new order
Chaos.
Well, not chaos. There was work to do, and I had to train some of the others in what I do so they can replace me if I'm away. I think the idea is that we all know each other's jobs so we can mix and match as appropriate.
But for somebody used to having a very definitive schedule, it was chaos.
I was summoned to have a discussion with my boss on Thursday - a week on the flip side of the event horizon.
I get the impression that this all happened above her, and quite likely for exactly the reason I think.
I've asked that other committee members (who are more on my side here) don't agitate anything right now. I am, obviously, somewhat miffed at how it all went down, but it has and that's that. Let's see how this all plays out.
Remember that I believe in the concept of things happening for a reason? I'll be buggered if I know (or can think of) the reason for this change, but like I said, let's see how it goes.
As for the week? I hurt. Doing the industrial washing up is exercising a whole different set of muscles to wiping tables and scrubbing toilets. But this is to be expected. I will, however, have to stop trying to pick up a dozen baking trays at once. It was no big deal when I started here and was 35. I'm less than a year to half a decade of crustiness, and I'm really not up to flexing like that.
No, I'm not Vin Diesel
Set off to work this morning. It was -3 and clear, but the clouds in the direction of work had "snow" written all over them.
For most of the journey, there was no problem.
Until I got to the roundabout in the town before work. If you've been watching my videos, it's the one where the van tried to cut in front of me.
I was doing something like 15kph, because I like to go around the roundabout properly rather than driving over it like everybody else.
That's when it became clear that my back end was swinging around faster than the front.
So... in a toy car doing a speed barely faster than a run, I drifted a tiny roundabout.
Feel free to laugh.
I didn't hit anything, and it was over before I had any time to even think about how to respond. The car behind me, however, saw this and slammed on the brakes. And, yeah, that didn't quite go as planned.
He/she didn't hit anything either, but had to reverse and slowly turn to be heading in the right direction.
The road from that roundabout to the big one before the supermarket, maybe a kilometre or so? Total skating rink. I could feel the car shuddering as the wheels made and unmade contact. As it was a straight line, we (myself and the car behind) did it at about 25. It was a 50 zone.
As I came to the big roundabout, a jam sandwich went whizzing by, blues flashing but no siren. I'm guessing somebody had a worse morning than the two of us.
It's supposed to be subzero in the morning until Wednesday, but there's no rain forecast so hopefully the moments of sun will keep things dry so there's no more ice.
Then it's supposed to be a high of 14 for two days, which seems like either an anomaly or an apology.
Parcels
Well, my CD from Canada was supposed to have arrived on Tuesday.
Instead, I got a letter in the mail saying that I had to pay import duty of €11 - on a CD costing €3 with around €12 postage.
I wasn't going to be around to deal with this, so I went to the La Poste website, and elected to pay the import duties on-line.
€5.
This was broken down as €3 for the actual import duty (20% of the cost of the item plus shipping, rounded up to a whole euro amount), plus a fee of €2 for "handling".
First of all, what the actual hell are they doing applying tax to the shipping charge?
But secondly, and more importantly, why did my post person quote me €11? The website itself made it quite clear that by paying on-line, I would economise €6. And I did.
But, wait, this amount is set by and paid to the government. It's import duty, with a small handling charge added on top. So what justifies trying to charge more than double if I don't do it on-line?
The rule is clear. If the postperson comes along with a parcel with import duty, to say no - keep it, I'll pay the duty on-line, you can bring it out in a couple of days.
Which is absolutely ridiculous.
Anyway, nothing came on Wednesday. I left a message for the postie to say that the tax had been paid. She left me a message to say she had spoken to her boss and she thinks I made an error as it was for €11, not €5, and as such the duty hasn't been marked as paid.
As it turns out, the duty was marked as unpaid because it took until 1pm the following day for it to be processed. What, is it done by hand?
My postie left her mobile number, so I sent a few text messages for a discussion that was increasingly surreal. Eventually I took a photo of the note that had the phone number and sent that by MMS.
The reply... I was speaking to somebody completely different at the other end of the country. My postie had written her number down incorrectly.
I apologised profusely, and the woman I was talking to said she hopes I get it sorted - import duty is a nightmare.
I wasn't expecting it on Thursday. I mean, everybody was on strike, right?
It arrived Thursday.
Bunny ears.
I had ordered something else, from the UK this time. There was no import duty as the item had already been taxed and it was a reciprocal agreement, which I guess Canada doesn't have.
It left somewhere near Leeds, went to Hinkley (as in, the nuclear reactor in Somerset?), then to Paris, then to Rennes, and finally out to me. It took three days. Pretty impressed by the speed of that.
Anyway, I went to the track and trace and it said that my only options were to have it delivered or to pick it up from the depot in Rennes. I couldn't ask for it to be left at my local supermarket.
I ticked a box to give permission for the parcel to be left, and to be left without signature and that I'd accept the risk of that.
The driver allegedly passed, discovered I wasn't home, and didn't deliver the parcel as I was absent.
Thankfully he didn't take it back to the depot. He left it at a supermarket in a town twenty miles away. The place it was left is, actually, our "sub-head" town because... it's complicated and the French are very territorial. But it's bloody annoying because if I look to have Amazon leave anything at a pickup point, they suggest this place because of how French administration works, and don't ever offer to leave parcels in the closer town where I work because... FFS.
Anyway, there would be a receipt.
I say allegedly because I went home to pick up the little slip that was left in the letterbox... except there was no slip. So I'm not sure whether the driver even bothered to turn up, or just looked at the long driveway and thought "sod this" and marked me as being absent.
I went to the supermarket anyway (a journey twice as long as cutting across directly from work) and handed over my (French) ID card. Well, Residency Permit. It had my name, address, and an up to date photo to demonstrate that the government attests that the lifeform standing in front of the person is supposed to be wandering around.
Thankfully the person at the service desk looked it up by address and went and fetched it. Nothing to sign, only scan the code and call it delivered.
So the rule is clear. Just don't order stuff from overseas.
Which, knowing how protectionist the government can be, is probably exactly the intended idea. Pffft.
The Met
So a Met officer raped a bunch of women, not to mention stripping one woman and imprisoning her in a tiny cupboard under the stairs.
Actually, that's badly understating it.
With a known count of 48 rapes, he's one of the worst sex offenders in modern British history. All the more egregious that he was a serving officer of the Met, which led others (police and prosecutors) to tell the woman that claims like this against a police officer wouldn't be believed. Especially as he threatened to plant drugs in one person's car, with a "who are they going to believe?" question.
He's going to be sentenced, and may well go behind bars for a long time. Really, six foot deep is where he belongs.
However the continual rancid stories about the Met suggests that perhaps the best idea is to disband it completely and rebuild it from the beginning with an entirely new workforce taken from around the country. Former Met officers can move to other police positions, and hopefully it'll break up any comraderie as well as shaking out the bad people (of which there may be over a thousand).
There is something horribly broken within the Met, and it looks like either Cressida Dick was complicit or sleepwalking through the job.
Either way, when an entire gender has justifiable reason to fear the police, pathetic platitudes won't cut it. Time to rip and retry.
Ray casting 2
A little gift for the weekend.
I gave you code for rotating the vectors to any arbitrary angle. So it wasn't hard to plug this into the program to actually do this according to the keys pressed, which provides rotation. We move 0.05 radians, which is about 2.8°.
Then to check the location of a map reference with an offset added, and if it's an empty tile, to do the move. This provides forward and backward movement.
There is no attempt at throttling or maintaining a steady rate of movement. It's just the bare bones to have a map that you can actually move around in.
Five versions of the program are provided in the archive. Listed in order of effective speed (as I wandered around the map):
Name
FPS
What it is
raycast2
18-19
The original source with comments.
raycast2nc
19-23
The original source with no comments.
raycast2cr
25-34
Crunched source.
raycast2fpa
25-35
Compiled with ABC† set to use FPA maths.
raycast2vfp
35-65
Compiled with ABC† set to use VFP maths.
† - built from a source that uses ColourTrans_SetGCOL to set the colours as ABC still doesn't support the GCOL r,g,b form.
Now, all you're missing is the programs (Zip, 16,442 bytes).
I'm just going to dump the entire commented source here. The changes are described, and shouldn't be too hard to work out. Though, I would imagine this might just be a step too far for a BBC Master version. ☺
REM >raycast2
REM
REM Rick's simple ray-caster, version 2
REM * Added movement (rotation and foreward/backward)
REM
REM https://heyrick.eu/blog/index.php?diary=20230120
REM
REM Basic demonstration of principle
REM
REM The principle is as described by Lode Vandevenne at
REM https://lodev.org/cgtutor/raycasting.html
REM
REM What's worth noting here is that we do *NOT*
REM work in degrees like a normal ray-caster, so
REM the code that follows is rather more compact
REM than you may see in other places, but it does
REM require competent floating point maths support.
REM
ON ERROR PROCerror
REM 640x480 in 256 colours; it's VGA so
REM everything ought to support this.
MODE 28
REM The physical size of the screen
width% = 640
height% = 480
REM Set up triple buffering
SYS "XOS_ReadModeVariable", -1, 7 TO ,, scrsize%
scrwant% = scrsize% * 3
SYS "XOS_ReadDynamicArea", 2 TO , scrcurr%
screxpa% = scrwant% - scrcurr% : REM How much to enlarge by
IF ( screxpa% > 0 ) THEN
SYS "XOS_ChangeDynamicArea", 2, screxpa% TO ; f%
IF (f% AND 1) THEN ERROR 123, "Not enough screen memory"
ENDIF
REM Set up other screen stuff
SYS "Hourglass_Smash"
MOUSE OFF
SYS "OS_RemoveCursors"
SYS "OS_Byte", 114, 0 : REM Shadow modes
bank% = 1
PROCswitchbank
REM The size of the 2D map
REM Let's keep it simple for now
mapx% = 16
mapy% = 8
DIM map%(mapx%, mapy%)
FOR loopy% = 7 TO 0 STEP -1
FOR loopx% = 0 TO 15
READ map%(loopx%, loopy%)
NEXT
NEXT
REM 0 = Empty
REM 1 = Red square
REM 2 = Green square
REM 3 = Blue square
DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DATA 1,0,0,0,3,3,0,0,0,0,0,0,0,0,0,1
DATA 1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1
DATA 1,0,0,0,3,0,0,0,1,0,2,0,0,0,0,1
DATA 1,0,3,0,0,0,3,0,1,0,0,0,0,0,0,1
DATA 1,0,0,0,2,0,0,0,0,0,3,0,0,0,0,1
DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
REM /|\
REM |
REM Viewer is here, fourth row up. looking to the LEFT.
REM Note that as of now, it's lots of floating point maths
REM Where in the map does the viewer start?
ourx = 14
oury = 4
REM Looking to the left
xdir = -1
ydir = 0
REM The projection plane, in 2D
REM This MUST be perpendicular to the direction.
xproj = 0
yproj = 0.65
REM yproj being 0.65 above corresponds to a field of view of
REM about 65 degrees, which is a good value for a old style
REM squarish screen, such as the VGA mode used here.
REM If using a 16:9 display, you'll need a wider field of view
REM because of the extra width. Try 0.85 which equals a field of
REM view of about 80 degrees.
REM
REM To convert the above value into degrees for a viewing angle:
REM value = 0.65
REM PRINT ((ATN(value / 1) * 2) / PI) * 180
REM (this converts the value into radians, and then into degrees)
REM
REM A loop to repeatedly draw according to defined location and angle
timeout% = TIME + 100
fcnt% = 0
fps% = 0
WHILE TRUE
PROCswitchbank
CLS
REM Draw the floor
GCOL 48, 48, 48 : REM Dark grey
RECTANGLE FILL 0, 0, (width% << 1), height%
REM And now the ceiling
GCOL 98, 98, 98 : REM Lighter grey
RECTANGLE FILL 0, height%, (width% << 1), height%
REM Now, cast rays for each scrcol across the screen, starting from the left.
FOR scrcol% = 0 TO (width% - 1)
REM Let's do the easy inits first.
REM For now, let's look to see what map location we are in.
mapx% = ourx
mapy% = oury
REM We use an integer here in order to lose the fractional part,
REM as in this case we don't care how far along in any position
REM the viewer is, only which block matches where the viewer is.
REM These two values represent the distance from our current
REM (exact) location to the next square boundary. This is
REM updated as we step along.
xedge = 0
yedge = 0
REM The step values are -1 if it's a negative step, or 1 if it's a
REM positive step. Initially zero as the stepping hasn't been set up.
xstep% = 0
ystep% = 0
REM Has a wall been hit?
wallhit% = FALSE
REM Which side was hit? FALSE for an X side, TRUE for a Y side
side% = 0
REM This will be the distance to the actual wall that we're going
REM to draw on the screen.
towall = 0
REM Now for the freaky maths
REM Calculate our angle offset for the desired screen column.
REM This goes from -1 on the left, to 0 in the middle, to 1 on the right.
angle = (2.0 * (scrcol% / width%)) - 1
REM Now set up two rays. Remember when we are talking about X and Y
REM we are talking about the GRID that represents the array that our
REM map is in. It isn't X,Y on the screen, or in some 3D space, it
REM is the imaginary X,Y divisions between array elements.
REM Or, to put it more simply, imagine that you have written the
REM contents map% on a piece of squared paper like you used in maths
REM class. The horizontal lines are your X positions, and the vertical
REM lines are your Y positions.
xray = xdir + (xproj * angle)
yray = ydir + (yproj * angle)
REM Now we work out how far we must step from one square edge to
REM the next. Since the rays travel in a straight line, we only
REM need to calculate this once.
IF (xray <> 0) THEN xdelta = ABS(1 / xray) ELSE xdelta = 12345678
IF (yray <> 0) THEN ydelta = ABS(1 / yray) ELSE ydelta = 12345678
REM To explain the above a little better, the actual calculation
REM would be:
REM xdelta = SQR(1 + (yray * yray) / (xray * xray))
REM but because we already did some of this calculation when sorting
REM out xray/Y above, and we're only interested in the RATIO
REM between the X and the Y, all of this can be simplified down to
REM simply dividing 1 by the ray distance.
REM Now we work out which stepping to use, and our initial distance
REM to the edge of the current square.
IF ( xray < 0 ) THEN
REM We're moving leftwards in the map
xstep% = -1
xdist = ( ourx - mapx% ) * xdelta
ELSE
REM We're moving rightwards in the map
xstep% = 1
xdist = ( (mapx% + 1) - ourx ) * xdelta
ENDIF
IF ( yray < 0 ) THEN
REM We're moving downwards in the map
ystep% = -1
ydist = ( oury - mapy% ) * ydelta
ELSE
REM We're moving upwards in the map
ystep% = 1
ydist = ( (mapy% + 1) - oury ) * ydelta
ENDIF
REM Now look for a wall
WHILE ( wallhit% = FALSE )
IF ( xdist < ydist ) THEN
REM The next X boundary is closer, so let's step to it
mapx% += xstep%
xdist += xdelta
side% = FALSE
ELSE
REM The next Y boundary is closer, so let's step to it
mapy% += ystep%
ydist += ydelta
side% = TRUE
ENDIF
REM Was something hit?
IF ( map%(mapx%, mapy%) <> 0 ) THEN wallhit% = TRUE
ENDWHILE
REM Do you see how the two rays worked here? They are both
REM being cast together at the same time, and we're simply
REM stepping to look at whichever happens to be the closest.
REM Now that we know that something has been hit, we can work
REM out the wall distance. This is easy, we simply subtract the
REM delta that we stepped over from the accumulated distance to
REM the next side.
IF side% = FALSE THEN
REM It's an X boundary
towall = xdist - xdelta
ELSE
REM It's a Y boundary
towall = ydist - ydelta
ENDIF
IF (towall = 0) THEN towall = 1
REM Now we have the wall distance, work out how big this line should be
drawsize% = height% / towall
REM Now work out the lowest and highest pixel to actually draw on
REM the screen; clipping it if it goes off the screen.
drawbot% = (-drawsize% / 2) + (height% / 2)
IF ( drawbot% < 0 ) THEN drawbot% = 0
drawtop% = ( drawsize% / 2) + (height% / 2)
IF ( drawtop% >= height% ) THEN drawtop% = ( height% - 1)
REM Now work out what colours we want
col% = 127
IF (side% = FALSE) THEN col% += 128
CASE map%(mapx%, mapy%) OF
WHEN 1 : GCOL col%, 0, 0 : REM Red
WHEN 2 : GCOL 0, col%, 0 : REM Green
WHEN 3 : GCOL 0, 0, col% : REM Blue
ENDCASE
REM And, finally, draw the line, with correction between
REM OS units and pixels for MODE 28.
MOVE (scrcol% << 1), (drawbot% << 1)
DRAW (scrcol% << 1), (drawtop% << 1)
NEXT
REM FPS tracking
fcnt% += 1
IF ( TIME >= timeout% ) THEN
timeout% = TIME + 100
fps% = fcnt%
fcnt% = 0
ENDIF
REM A screen has been drawn, so now handle keypresses
REM Esc . . . . . . . Quit ;)
REM Left / Right . . . Rotate
REM Up . . . . . . . . Forwards
REM Down . . . . . . . Backwards
REM F . . . . . . . . Show FPS
REM S . . . . . . . . Screenshot
REM LEFT or RIGHT
IF ( FNkey(25) ) OR ( FNkey(121) ) THEN
IF FNkey(25) THEN rot = 0.05 ELSE rot = -0.05
oldx = xdir
xdir = (xdir * COS(rot)) - (ydir * SIN(rot))
ydir = (oldx * SIN(rot)) + (ydir * COS(rot))
oldx = xproj
xproj = (xproj * COS(rot)) - (yproj * SIN(rot))
yproj = (oldx * SIN(rot)) + (yproj * COS(rot))
ENDIF
REM UP
IF ( FNkey(57) ) THEN
IF ( map%(ourx + (xdir * 0.1), oury) = 0 ) THEN ourx += xdir * 0.1
IF ( map%(ourx, oury + (ydir * 0.1)) = 0 ) THEN oury += ydir * 0.1
ENDIF
REM Down
IF ( FNkey(41) ) THEN
IF ( map%(ourx - (xdir * 0.1), oury) = 0 ) THEN ourx -= xdir * 0.1
IF ( map%(ourx, oury - (ydir * 0.1)) = 0 ) THEN oury -= ydir * 0.1
ENDIF
REM F(PS)
IF ( FNkey(67) ) THEN
PRINTTAB(0,0);STR$(fps%)+" fps"
ENDIF
REM S for a Screenshot
IF ( FNkey(81) ) THEN
OSCLI("ScreenSave $._3dscene"+MID$(TIME$,17,2)+MID$(TIME$,20,2)+MID$(TIME$,23,2))
ENDIF
ENDWHILE
END
:
DEFPROCerror
REM If we abort with shadow modes set up, RISC OS will poop its nappy
REM So this restores the screen state back to what it was on entry
VDU 4
PROCdrawbank(0)
PROCshowbank(0)
SYS "OS_Byte", 114, 1 : REM Non-shadow
SYS "ColourTrans_SetTextColour", &00000000, (1<<7) : REM Background
SYS "ColourTrans_SetTextColour", &FFFFFF00, 0 : REM Foreground
PRINTTAB(0,0);REPORT$+" at "+STR$(ERL)
END
ENDPROC
:
DEFPROCdrawbank(w%)
REM What screen bank are we drawing to?
SYS "XOS_Byte", 112, w%
ENDPROC
:
DEFPROCshowbank(w%)
REM What screen bank is the user looking at?
SYS "XOS_Byte", 113, w%
ENDPROC
:
DEFPROCswitchbank
REM Furtle with the screen banks
WAIT
PROCshowbank(bank%)
bank% = (bank% MOD 3) + 1
PROCdrawbank(bank%)
ENDPROC
:
DEFFNkey(k%)
REM Returns TRUE if the nominated key is pressed, else FALSE
SYS "OS_Byte", 121, (k% EOR &80) TO , r%
IF r% = &FF THEN =TRUE
=FALSE
Have fun!
By the way - If you're trying this and wondering why it suddenly speeds up when there are lots of boxes on-screen (which is sort of the opposite to what you'd expect), fridge brilliance is that it's because there's actually less needing to step through the rays before we register a hit, so the code is doing less work the more boxes are on screen.
Your comments:
Please note that while I check this page every so often, I am not able to control what users write; therefore I disclaim all liability for unpleasant and/or infringing and/or defamatory material. Undesired content will be removed as soon as it is noticed. By leaving a comment, you agree not to post material that is illegal or in bad taste, and you should be aware that the time and your IP address are both recorded, should it be necessary to find out who you are. Oh, and don't bother trying to inline HTML. I'm not that stupid! ☺ ADDING COMMENTS DOES NOT WORK IF READING TRANSLATED VERSIONS.
You can now follow comment additions with the comment RSS feed. This is distinct from the b.log RSS feed, so you can subscribe to one or both as you wish.
This web page is licenced for your personal, private, non-commercial use only. No automated processing by advertising systems is permitted.
RIPA notice: No consent is given for interception of page transmission.