We are going to modify video.bmx in order to get a rotated image. Select the whole type TVideo and replace it with this one:
Type Tvideo
Field screen: TPixmap
Field screenptr: Int Ptr
Field pitch: Int
Field x: Int
Field y: Int
Method Init()
screen = CreatePixmap(224, 256, PF_RGBA8888)
screen.ClearPixels(0)
screenptr = Int Ptr(screen.pixels)
pitch = screen.pitch Shr 2
x = 20
y = 40
DebugLog("Video initialized.")
End Method
Method Draw()
CopyScreen()
SetColor(255, 255, 255)
' Perform a fast OpenGL drawpixel instead of DrawPixmap because it's slow
FastGLDrawPixmap(screen, x, y)
SetColor(200, 200, 200)
DrawLine(x, y-1, x+screen.width, y-1)
DrawLine(x+screen.width, y, x+screen.width, y+screen.height)
DrawLine(x, y+screen.height, x+screen.width, y+screen.height)
DrawLine(x-1, y-1, x-1, y+screen.height)
End Method
Method CopyScreen()
For Local j:Int=0 Until 224
Local src:Int = $2400 + (j Shl 5)
Local dst:Int = 255*pitch + j
For Local i:Int=0 Until 32
Local vram:Byte = cpu.memoryptr[src]
src :+ 1
For Local b:Int=0 Until 8
Local color:Int = 0
If (vram&1) Then color = $FFFFFFFF
screenptr[dst] = color
dst :- pitch
vram = vram Shr 1
Next
Next
Next
End Method
End Type
You might notice a few difference: first, the pixmap itself is now 224 x 256 which is what the rotated display really should be. Next, CopyScreen() has been modified and is a bit more complex. Take your time to read it if you need to. You may also compile & run, the game should work perfectly and the screen orientation should be right this time.
If you ever tried an arcade emulator or old console emulator on your computer, you may have seen some scanline effects at some point. This is a visual effect that more-or-less recreate the look of real arcade monitor by showing horizontal line imperfection. We can do that too, it will make our emulator have a 'retro' look. However we'll need to scale the output because at the moment, the display is fairly small. Also, since the real arcade machine had colored transparent strips on the screen to tint various portion of the game, we'll do that too. Replace the whole TVideo type yet again with this 2x scaled colorful version:
Type Tvideo
Field screen: TPixmap
Field screenptr: Int Ptr
Field pitch: Int
Field x: Int
Field y: Int
Field color:Int[32,2]
Field color2:Int[32,2]
Field color3:Int[32*2]
Method Init()
screen = CreatePixmap(224*2, 256*2, PF_RGBA8888)
screen.ClearPixels(0)
screenptr = Int Ptr(screen.pixels)
pitch = screen.pitch Shr 2
x = 20
y = 40
For Local i:Int=0 Until 32
color[i, 0] = 0 ' Black
color2[i, 0] = EndianFlip($44444400) ' Black
If(i>=26 And i<=27) Then
color[i, 1] = EndianFlip($FF000000) ' Red
color2[i, 1] = EndianFlip($AA000000) ' Red
Else If(i>=2 And i<=7)
color[i, 1] = EndianFlip($00FF0000) ' Green
color2[i, 1] = EndianFlip($00AA0000) ' Green
Else
color[i, 1] = EndianFlip($FFFFFF00) ' White
color2[i, 1] = EndianFlip($AAAAAA00) ' White
End If
Next
DebugLog("Video initialized.")
End Method
Method Draw()
CopyScreen()
SetColor(255, 255, 255)
' Perform a fast OpenGL drawpixel instead of DrawPixmap because it's slow
FastGLDrawPixmap(screen, x, y)
SetColor(200, 200, 200)
DrawLine(x, y-1, x+screen.width, y-1)
DrawLine(x+screen.width, y, x+screen.width, y+screen.height)
DrawLine(x, y+screen.height, x+screen.width, y+screen.height)
DrawLine(x-1, y-1, x-1, y+screen.height)
End Method
Method CopyScreen()
For Local j:Int=0 Until 224
Local src:Int = $2400 + (j Shl 5)
Local dst:Int = (screen.height-2)*pitch + j Shl 1
For Local i:Int=0 Until 32
Local vram:Byte = cpu.memoryptr[src]
src :+ 1
For Local bit:Int=0 Until 8
screenptr[dst] = color[i, vram&1]
screenptr[dst+1] = color2[i, vram&1]
dst :- pitch Shl 1
vram = vram Shr 1
Next
Next
Next
End Method
End Type
This is the very nice visual result you should get:
In close up view, our 'pixel / scanline' effect looks like this:
Congratulations, you did it! The emulator is completed. I hope you enjoyed this tutorial as much as I enjoyed sharing it with you. This project may have demonstrated that Blitzmax is fast enough to do emulation of old machines. More importantly, it might have given you the incredible feeling of seeing a emulated machine come to life by your own work. I will put a complete source ZIP file on the tutorial home page, for those of you that code didn't ran properly or those that want to get straigth to the finish line. I have added a 'break point' system by pressing 'B' and then Enter or Space bar to execute one instruction at a time.
Have fun and I hope to see you in another tutorial some day!

