Page 1 of 1

What's the fastest way for showing own characters?

Posted: Tue Aug 11, 2009 3:06 pm
by infratec
Hi together,

no, I'm not a game programmer. An that's my problem at the moment.
Years ago I've written an emulator for my old Sharp MZ-700 (free available on the net with sourcecode included).
I'm shure it was (or is) the fastest emulator available (since my computer was slow, I used every trick to speed it up :)).
Unfortunately it works only up to Win98, since I make massive use of direct hardware access.
Now I decided to port it to PureBASIC to use it also on newer windows and maybe also Linux.
And here my problems starts.

What is te fastest and best way to implement an own character set?

I tried it first with sprites, but this has the disadvantage, that I can not change the foreground color.
Than I wrote a program to convert the charset to a font.
But I have to use also chr(0) as output, which is not possible with DrawText().

Also I have problems with the double buffering.
This takes to long time.
I have to emulate the graphic RAM and so I have to write at each access of this memory. So when the emulated computer clears the screen, I have a lot of single Drawtext() commands with FlipBuffers() before and behind. And not only for the characters itself, also for the colour RAM, because than I also have to redraw the character with the new colours.

So what is the best way to implement an own character set, which is also changeable by program, when I also have independent colour informations for the characters?

Best regards

Bernd

Posted: Thu Aug 13, 2009 4:26 am
by GBeebe
If your font sprites where flat black rgb(0, 0, 0) and flat white rgb(255, 255, 255) you could cycle through each pixel and replace any white ones with the desired color.

As for speed, maybe make a sprite layer holding all the text and only updating it when the text changes instead of redrawing "sentences" each loop.

Posted: Thu Aug 13, 2009 9:38 am
by infratec
Hi GBeebe,

thanks for your reply. But that is exactly what I want to avoid:
That I have to 'draw' each pixel again, when I have to show a character.
That was the reason why I wrote a program which converts the character ROM to a font.
One big disadvantage of this methode is, that I need different fonts for windows and for Linux.

So I have to look around. Maybe I find a better solution.

Bernd

Posted: Thu Aug 13, 2009 10:21 am
by Thalius
i use Sprites with Clipping for that. Asfor changing the Foregroudncolor just dont Antialise em and replace or blend colors on a single Spritetexturetable. Creating a couple of thoose automatically ( currently i still use the old irrlicht tool for that ). is also np :)

Fast n lazy ;) But ehm whats it for - maybe i got anotehr idea.

Cheers,
Thalius

Posted: Thu Aug 13, 2009 1:13 pm
by wilbert
I haven't used PB in a while.
It seemed like a challenge to try this since I like the old 8 bit computers.
Here's my attempt. It redraws the entire display but on my computer that takes about 1 msec. See for yourself if you can use it.

Code: Select all

Global *RAM64K.l

*RAM64K    = AllocateMemory(65536)

*MZ700Display = AllocateMemory(64086)
CopyMemory(?BMData, *MZ700Display, 86)

Procedure UpdateDisplay()
  !pushad
  !mov esi,[p_RAM64K]
  !add esi,$D000
  !mov edi,[p_MZ700Display]
  !add edi,63766
  !mov ch,25
  !ud_l0:
  !mov cl,40
  !ud_l1:
  !mov edx,esi
  !mov bl,[edx]
  !add edx,$800
  !mov bh,[edx]
  !mov edx, ebx
  !rol dh,1
  !and edx,$1ff
  !shl edx,3
  !add edx,l_charrom
  !mov bl,bh
  !and bl,7
  !shr bh,4
  !and bh,7
  !push ecx
  !mov ch,8
  !ud_l2:
  !mov al,[edx]
  !mov cl,8
  !ud_l3:
  !rcl al,1
  !jnc ud_l4
  !mov [edi],bh
  !jmp ud_l5
  !ud_l4:
  !mov [edi],bl
  !ud_l5:
  !inc edi
  !dec cl
  !jnz ud_l3
  !inc edx
  !sub edi,328
  !dec ch
  !jnz ud_l2
  !add edi,2568 
  !inc esi
  !pop ecx
  !dec cl
  !jnz ud_l1
  !sub edi,2880
  !dec ch
  !jnz ud_l0
  !popad
EndProcedure

Procedure MZ_Poke(addr.w, val.b)
  !xor edx,edx
  !mov dx,[p.v_addr]
  !add edx,[p_RAM64K]
  !mov al,[p.v_val]
  !mov [edx],al
EndProcedure

Procedure.b MZ_Peek(addr.w)
  !xor eax,eax
  !xor edx,edx
  !mov dx,[p.v_addr]
  !add edx,[p_RAM64K]
  !mov al,[edx]
  ProcedureReturn
EndProcedure

If OpenWindow(0, 0, 0, 320, 200, "MZ700Display", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If InitSprite() And OpenWindowedScreen(WindowID(0), 0, 0, 320, 200, #False, 0, 0)

    MZ_Poke($D000, $41)
    MZ_Poke($D800, $F0)
    MZ_Poke($D028, $97)
    MZ_Poke($D828, $F0)

    UpdateDisplay()
    CatchSprite(0, *MZ700Display)

    DisplaySprite(0, 0, 0)

    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow

  EndIf
EndIf

End

DataSection

  BMData:

    Data.b $42, $4D
    Data.l 64086, 0, 86, 40, 320, 200
    Data.w 1, 8
    Data.l 0, 64000, 0, 0, 8, 0
    Data.l $00000000 ; palette color 0
    Data.l $000000FF ; palette color 1
    Data.l $00FF0000 ; palette color 2
    Data.l $00FF00FF ; palette color 3
    Data.l $0000FF00 ; palette color 4
    Data.l $0000FFFF ; palette color 5
    Data.l $00FFFF00 ; palette color 6
    Data.l $00FFFFFF ; palette color 7

  CharROM:

    ; Character set 0

    Data.q $0000000000000000,$004242427E422418,$007C22223C22227C,$001C22404040221C,$0078242222222478,$007E40407840407E,$004040407840407E,$001C22424E40221C
    Data.q $004242427E424242,$001C08080808081C,$003844040404040E,$0042444870484442,$007E404040404040,$004242425A5A6642,$004242464A526242,$0018244242422418
    Data.q $004040407C42427C,$001A244A42422418,$004244487C42427C,$003C42023C40423C,$000808080808083E,$003C424242424242,$0018182424424242,$0042665A5A424242
    Data.q $0042422418244242,$000808081C222222,$007E40201804027E,$003E10103810120C,$0000000F08080808,$000000F808080808,$0808080F08080808,$000000FF08080808
    Data.q $003C42625A46423C,$003E080808281808,$007E40300C02423C,$003C42023C02423C,$0004047E24140C04,$003844020478407E,$003C42427C40201C,$001010100804427E
    Data.q $003C42423C42423C,$003804023E42423C,$000000007E000000,$0000007E007E0000,$1008080000080000,$0040201008040200,$0018180000000000,$1008080000000000
    Data.q $000000000000FF00,$4040404040404040,$FF80808080808080,$FF01010101010101,$00000000FF000000,$1010101010101010,$000000000000FFFF,$C0C0C0C0C0C0C0C0
    Data.q $0000FF0000000000,$0404040404040404,$FFFFFFFF00000000,$0F0F0F0F0F0F0F0F,$FF00000000000000,$0101010101010101,$FFFF000000000000,$0303030303030303
    Data.q $0010080804080810,$003E1C7F7F3E1C08,$0103070F1F3F7FFF,$FFFFFFFFFFFFFFFF,$00081C3E7F3E1C08,$0010207F20100000,$001C086B7F6B1C1C,$003C7E7E7E7E3C00
    Data.q $003C424242423C00,$001000100C02423C,$FFC381818181C3FF,$0808040300000000,$101020C000000000,$FFFEFCF8F0E0C080,$FF7F3F1F0F070301,$0000080000080000
    Data.q $000808082A1C0800,$000E18306030180E,$003C20202020203C,$00081C3E7F7F7F36,$003C04040404043C,$001E204C564A221C,$80C0E0F0F8FCFEFF,$0070180C060C1870
    Data.q $00081C2A08080800,$0002040810204000,$0004027F02040000,$0F0F0F0FF0F0F0F0,$0808080F00000000,$080808F800000000,$080808F808080808,$080808FF00000000
    Data.q $001414543E010000,$0008000008080808,$0000000000242424,$0024247E247E2424,$00081C0A1C281E08,$0046261008646200,$003A444A30484830,$0000000000100804
    Data.q $0004081010100804,$0020100808081020,$000008083E080800,$00082A1C3E1C2A08,$F0F0F0F00F0F0F0F,$8142241818244281,$00000000C0201010,$0000000003040808
    Data.q $00000000000000FF,$8080808080808080,$80808080808080FF,$01010101010101FF,$0000000000FF0000,$2020202020202020,$8040201008040201,$0102040810204080
    Data.q $000000FF00000000,$0808080808080808,$00000000FFFFFFFF,$F0F0F0F0F0F0F0F0,$00FF000000000000,$0202020202020202,$FFFFFF0000000000,$0707070707070707
    Data.q $0018181818181818,$003A443C04380000,$005C6242625C4040,$003C4240423C0000,$003A4642463A0202,$003C407E423C0000,$001010107C10120C,$3C023A46463A0000
    Data.q $00424242625C4040,$001C080808180008,$38440404040C0004,$0044685048444040,$001C080808080818,$0049494949760000,$00424242625C0000,$003C4242423C0000
    Data.q $40405C62625C0000,$02023A46463A0000,$00404040625C0000,$007C023C403E0000,$000C1210107C1010,$003A464242420000,$0018244242420000,$0036494949410000
    Data.q $0044281028440000,$3C023A4642420000,$007E2018047E0000,$003A443C04380024,$1008040201000000,$0000000080601C03,$00000000010638C0,$0810204080000000
    Data.q $030C30C000000000,$0000FF000000FF00,$4444444444444444,$4444FF444444FF44,$0000000000081020,$0000004C32000000,$11AA44AA11AA44AA,$C0300C0300000000
    Data.q $00000000C0300C03,$00000000030C30C0,$004C52424A444438,$001A262222002200,$001C22221C002200,$003C424242420042,$0042427E42241842,$0018244242241842
    Data.q $8080404040202010,$8040402020180601,$0102020404186080,$0101020202040408,$1020204040408080,$0106182020404080,$8060180404020201,$0804040202020101
    Data.q $0000000102040810,$031C608000000000,$C038060100000000,$0000008040201008,$0008101020101008,$080808FF08080808,$0000000000221408,$007E000000000000
    Data.q $003E00081C3E1C1C,$FFF7E3D5F7F7F7FF,$FFF7F7F7D5E3F7FF,$FFF7FB81FBF7FFFF,$FFEFDF81DFEFFFFF,$FFBDBDBD81BDBDBD,$FFE3DDBFBFBFDDE3,$0000245AFF7E2418
    Data.q $00E047427E4247E0,$417F4908082A3E22,$221408083E081C1C,$000011D2FCD21100,$0000884B3F4B8800,$1C1C083E08081422,$3C7EE7FFDBFF7E3C,$3C429981A581423C
    Data.q $55AA55AA55AA55AA,$050A050A050A050A,$50A050A050A050A0,$0000000055AA55AA,$55AA55AA00000000,$008040A050A854AA,$0102050A152A55AA,$55AA54A850A04080
    Data.q $552A150A05020100,$1010202040408080,$0101020204040808,$0000000000382838,$002A542A542A5400,$0808040402020101,$8080404020201010,$0022555454C8C000
    Data.q $02FF020000000000,$0207020202020202,$02FF020202020202,$0002058850200000,$010204C422110E00,$8844221188442211,$8040202344887000,$C4A4948F94A4C400
    Data.q $232529F129252300,$B898A8C0C0A09088,$8890A0C0C0B8B0A8,$8040201F10204080,$002424E724240000,$08083E00003E0808,$0402040810201008,$AA55AA55AA55AA55
    Data.q $0000000000000000,$0000000070707000,$0000000007070700,$0000000077777700,$7070700000000000,$7070700070707000,$7070700007070700,$7070700077777700
    Data.q $0707070000000000,$0707070070707000,$0707070007070700,$0707070077777700,$7777770000000000,$7777770070707000,$7777770007070700,$7777770077777700

    ; Character set 1

    Data.q $0000000000000000,$EEAABA82BABAC67C,$FC86BABA84BA86FC,$7EC2BEA0A0BEC27E,$F88CB6AAAAB68CF8,$FE82BE8888BE82FE,$E0A0A0B888BE82FE,$7E82BAAEA0BE827E
    Data.q $EEAAAABA82BAAAEE,$FE82EE2828EE82FE,$7CC6BAEA0A1B111F,$E6AAB48888B4AAE6,$FE82BEA0A0A0A0E0,$EEAAAABAAAAA82FE,$EEAAAAB2A28A9AEE,$7CC6BAAAAABAC67C
    Data.q $E0A0BC86BABA86FC,$7CC2B2AABABAC67C,$E6AAB484BABA86FC,$FC86FA7AC4BEC27E,$3828282828EE82FE,$7CC6BAAAAAAAAAEE,$102854AAAAAAAAEE,$FE82AAAABAAAAAEE
    Data.q $C6AA54282854AAC6,$382828284492AAEE,$FE825E2814FA82FE,$00007EFF90A04000,$00007EFF09050200,$009254387CD67C00,$00925438FE385492,$000000FE54380000
    Data.q $7C829AAAAAB2827C,$7C446C2828684838,$FE422E14CABA827C,$FC82FA2222FA82FC,$1CF682B65424140C,$FC86FA7A84BE82FE,$7C82BA82BCBE827E,$7050502814FA82FE
    Data.q $7C82BA827CBA827C,$FC82FA7A82BA827C,$003E22FAAABE88F8,$007C445F557D111F,$8142247EE7FF5A3C,$6624247EE7FF5A3C,$63363E777F2A1C08,$14363E777F2A1C08
    Data.q $6342FF7E5A3CA241,$C642FF7E5A3C4582,$0024422499BD5A00,$00C32418185AA581,$E724247EBD7E2400,$C34242247EBD7E24,$89DDFFD5ABFF5A3C,$2277FFD5ABFF5A3C
    Data.q $AAD5819981A5423C,$55AB819981A5423C,$3C7EFFFFE7664242,$1CFE3F0F0F3FFE1C,$424266E7FFFF7E3C,$387FFCF0F0FC7F38,$3C7EFFFFFFFF7E3C,$D6FE7C2828283810
    Data.q $03077EC77E070300,$081C1414143E7F6B,$C0E07EE37EE0C000,$4676763C183C0C3C,$7E5A5A3C183C243C,$626E6E3C183C303C,$6C24242424247E7E,$6624242424247E7E
    Data.q $3624242424247E7E,$3C3C7EFFB7F76322,$38FC3F0F3FFF6C38,$44C6EFEDFF7E3C3C,$1E3FFCF0FCFF361C,$3C3C7EFFBFFF7E3C,$3C7EFFFDFF7E3C3C,$1C3EFFFFFFFF361C
    Data.q $387CFFFFFFFF6C38,$3C3C183C3C3C3C18,$00007BFFFF7B0000,$183C3C3C3C183C3C,$0000DEFFFFDE0000,$3C3C283020206020,$000003070BFF4000,$040604040C143C3C
    Data.q $0000C0E0D0FF0200,$381010927C381010,$081031FF31100800,$1010387C92101038,$10088CFF8C081000,$0002044850607800,$0078605048040200,$001E060A12204000
    Data.q $004020120A061E00,$818181C3FF7E7E18,$1F7870F0F070781F,$187E7EFFC3818181,$F81E0E0F0F0E1EF8,$FF81BDA5A5ADA1BF,$FF01FD85A5BD81FF,$FD85B5A5A5BD81FF
    Data.q $FF81BDA5A1BF80FF,$FF007E003C001800,$0105155555150501,$0018003C007E00FF,$80A0A8AAAAA8A080,$3E1C08003E1C0800,$0011337733110000,$081C3E00081C3E00
    Data.q $0044667766440000,$000000E7A5E70000,$1038541010543810,$002442FF42240000,$7F0808081C22417F,$5555555555555555,$00FF00FF00FF00FF,$A542A50000A542A5
    Data.q $2442810000814224,$A0A0A0A0A09F80FF,$1115111511E501FF,$FFA0AFA0FF000000,$FF554141FF000000,$78303030FF809FA0,$1E0C0C0CFF01E111,$FF808F809580AA80
    Data.q $FF01E1015101A901,$08141010D5AB423C,$0000182424180000,$0018244242241800,$3C4281818181423C,$0000001818000000,$00003C3C3C3C0000,$007E7E7E7E7E7E00
    Data.q $3C429DA1A19D423C,$FFFFFFE7E7FFFFFF,$FFFFC3C3C3C3FFFF,$FF818181818181FF,$003C7EFF20203020,$3C4281FFFF81423C,$3C5A999999995A3C,$3C5A99FFFF995A3C
    Data.q $103854FEAAFE2800,$81808E8A4E40300F,$8101715172020CF0,$8180808E4040300F,$8101017102020CF0,$0F30404384888081,$F00C02C221110181,$0F30404087808081
    Data.q $F00C0202E1010181,$0F30404384838081,$F00C02C221C10181,$0F30404888878081,$F00C021211E10181,$7CFEFEFEFE541008,$3078783010080600,$004A2C6006345200
    Data.q $894A00C003005291,$FFFFFFFFF0E0C080,$FFC3C3FF02010000,$FFC3C3FF40800000,$FCFFFEFC1020C000,$FFFFFFFF0F070301,$0008141408281402,$FE4220102042FE00
    Data.q $3FFF7F3F08040300,$8648281010102000,$E7A5244242423C00,$00006C9282824400,$00006C92926C0000,$00006E90906C0200,$0010B05050101E00,$0010007C00100000
    Data.q $00515155555BF100,$FF9189A3C59189FF,$FFC3A59999A5C3FF,$925438EE38549200,$FF9999FFFF9999FF,$1010101010385492,$1038103810381038,$0000AAFFAA000000
    Data.q $7C0010107C101000,$427E427E427E427E,$00FF55555555FF00,$FF838CB0C0000000,$FFC1310D03000000,$FFFF7E3C00000000,$000000003C7EFFFF,$C0E0F0F0F0F0E0C0
    Data.q $03070F0F0F0F0703,$1F377FFF3F3F0C03,$FBFBF6EEDCB830C0,$0F030101040A0E0E,$FDFDFAF4F4F4747A,$3F607F6F46E44E04,$FC06FEF662277220,$070F1F101F1B313B
    Data.q $E0F0F808F8D88CDC,$30703E0E06070301,$0C0E7C7060E0C080,$8B7F370307060E1E,$D1FEECC0E0607078,$3F7FDF8C597B3301,$FCFEFB319ADECC80,$FF007F0F0F1F1F3F
    Data.q $FF00FEF0F0F8F8FC,$1F1F010204020100,$F8F8804020408000,$007F201F02020202,$00FE04F840404040,$0F0F1F3F7F737373,$F0F0F8FCFECECECE,$FF7F407F180F0F0F
    Data.q $FFFE02FE18F0F0F0,$F8444221214244F8,$FF050700000705FF,$FC868281818286FC,$0000807F40800000,$010101FF00000000,$000000FF01010101,$00000080808080FF
    Data.q $FF80808000000000,$080C0AF90A0C0800,$080C3AE93A0C0800,$008F8888FE48281F,$0F040209E640C040,$021F0A06E240C040,$0F010701EF40C040,$0F0107E14F20A040
    Data.q $FE806018061860C0,$7F01061860180601,$1F2A2A2A1D060100,$F3B1A9C911658F1B,$FE3E020718F0F74C,$FDF9818141319F7F,$9100418800400288,$1180044000880140
    Data.q $003079FFFD583000,$000C9EFFBF1A0C00,$0030F93FFD583000,$000C9FFCBF1A0C00,$381078FCBC682810,$BAFEBA3838AAEEBA,$BAEEAA3838BAFEBA,$E742FF9FFF42E700
    Data.q $E742FFF9FF42E700,$003E637F1CFC0000,$007CC6FE383F0000,$FF81A58181A581FF,$E7818100008181E7,$4020FE10FE080400,$1010101020242418,$1824240408080808
  
EndDataSection

Posted: Thu Aug 13, 2009 6:55 pm
by blueznl
I see loads of complex solutions :-) One way would be to put all characters as little bitmaps in one larger bitmap, them simply copy / paste that part of the bitmap.

Posted: Thu Aug 13, 2009 8:15 pm
by infratec
Hi together,

thank you for all your suggestions.
At the moment I try Wilbert's solution, since it is fast and portable.
I look how it works in my emulator.

@Wilbert:
Do you know the MZ-700?
Or from where did you know the video and the color address range?

Best regards,

Bernd

Posted: Thu Aug 13, 2009 8:24 pm
by infratec
Hi Wilbert,

interresting:

Code: Select all

start = ElapsedMilliseconds()

For n = 1 To 1000
    For i = 0 To 255
     ;MZ_Poke($D000 + i, i)
     ;MZ_Poke($D800 + i, $70)
     ;MZ_Poke($D140 + i, i)
     ;MZ_Poke($D940 + i, $F0)
      PokeB(*RAM64K + $D000 + i, i)
      PokeB(*RAM64K + $D800 + i, $70)
      PokeB(*RAM64K + $D140 + i, i)
      PokeB(*RAM64K + $D940 + i, $F0)
    Next i
Next n

Debug ElapsedMilliseconds() - start
The PureBASIC PokeB() is much faster. Only 78ms instead of 609ms with MZ_Poke().

Bernd

Posted: Thu Aug 13, 2009 9:11 pm
by Rescator
blueznl really earns his forum title, he's right.
If you look at most commercial games out there they either use a TrueType font or similar,
or they have a fontstrip in the form of a image/bitmap that contain all the characters, as blueznl said it's very easy to grab or blit just the part you need using a lookup table.

Posted: Thu Aug 13, 2009 9:43 pm
by infratec
Hi Rescator,

as I wrote already, I tried to use a font.

But:

1. I have to 'install' the font.
It works only when the fontfile is in \windows\Fonts\.

2. Linux uses a different font format, so I have double trouble.

3. I need also chr(0) which is not possible with PB DrawText().

4. The MZ-700 can generate own characters so I have to write the font
'on the fly' which is not possible, since I have always to unregister the font before I can manipulate the file (else it is 'in use')

So it seems that the idea of blueznl with the bitmap is the right way.

And if you look closer at the code of Wilbert, you can see, that he does exactly this.
In his case the image is one big sprite 320 by 200 which is the screen resolution of the MZ-700.
The update function generates the sprite out of the character data.

Now I have to check how fast this solution is.
Because I have to do this update and display sprite very very often.

In my original emulator, I used directly the graphic card to do this.
You can store your own characterset inside the graphic card!
So I had nothing to do with all that stuff, the graphic card handled all this for me.

I also tried all available virtual machines with my emulator,
but they didn't emulate this graphic card feature good enough.

I hope that I found a working solution.

Bernd

Posted: Fri Aug 14, 2009 5:30 am
by wilbert
Hi Bernd,

I didn't know the MZ700 but looked up the specifications.
The first computer we had at home was a MSX with a Z80A processor running at 3.58 MHz. I was curious about the MZ700 when you mentioned it. A lot of computers back them seemed to use the Z80 processor. The graphics of the MSX were a bit more complex but also had a mode combining character data and colors.

The routine I created does exactly that. Combining the information in the vram with the font data and turning it into a bmp. I don't see why you have to call the update very often. Computers back then had a screen refresh rate of 50Hz. But even calling it 25 times a second will give good enough results I suppose. You also can use a flag to detect if something has changed. If a value is poked into the MZ memory and the highest nibble is $D , you know it is in the vram range.

Wilbert

Posted: Fri Aug 14, 2009 9:22 am
by infratec
Hi Wilbert,

I've already done (yesterday night :) ), what you said.
In the main loop of the program I set a VBLANK flag every
MZ-700 20ms (depending on the Z80 instruction cycles).
I simply call your update(), Catch and DisplaySprite() at this point.
I think it is fast enough, but it is minimum 20 times slower than my old solution :cry: .
But better than all other tested stuff.

Thanks a lot.

Oh, for your information:
I use RAZE as Z80 emulator. I compiled it as dll, so I can use it simply in PB.
(hm, for Linux I need an other way)

Bernd

Posted: Fri Aug 14, 2009 10:09 am
by blueznl
infratec wrote: Hi Rescator,
as I wrote already, I tried to use a font.
1. I have to 'install' the font.
No, this is where you are wrong! Start up a graphic editor, create an image, and paste all characters of your font in that image, so first row A B C D second row E F G H etc.

Then just 'grab' part of that image so you have the character you want.

It's also platform independent as you're not loading fonts, you're only loading a single bitmap :-)

Posted: Fri Aug 14, 2009 11:00 am
by wilbert
@Blueznl,
I'm curious how you would do the recoloring.
The are 512 characters all of them 8 x 8 pixels. Both frontcolor and backcolor of each character can have 8 different values so there are 64 different color combinations.

@Infratec,
An improvement could be to use a flag for every character so only the ones that have been changed are updated. See for yourself if it makes a difference

Code: Select all

Global *RAM64K.l, *MZ700Display.l
Global FastAddr.l, FastVal.l

*RAM64K = AllocateMemory($10900)
*MZ700Display = AllocateMemory(64086)
CopyMemory(?BMData, *MZ700Display, 86)

Procedure UpdateDisplay()
  If PeekB(*RAM64K + $10800)
    PokeB(*RAM64K + $10800, 0)
    !pushad
    !mov esi,[p_RAM64K]
    !add esi,$10000
    !mov edi,[p_MZ700Display]
    !add edi,63766
    !mov ch,25
    !ud_l0:
    !mov cl,40
    !ud_l1:
    !mov edx,esi
    !mov bl,[edx]
    !add edi,8
    !and bl,bl
    !jz ud_l6
    !sub edi,8
    !mov byte [edx],0
    !sub edx,$3000
    !mov bl,[edx]
    !add edx,$800
    !mov bh,[edx]
    !mov edx, ebx
    !rol dh,1
    !and edx,$1ff
    !shl edx,3
    !add edx,l_charrom
    !mov bl,bh
    !ror bh,4
    !and bx,$0707
    !mov ebp,ecx
    !mov ch,8
    !ud_l2:
    !mov al,[edx]
    !mov cl,8
    !ud_l3:
    !rol al,1
    !jnc ud_l4
    !mov [edi],bh
    !jmp ud_l5
    !ud_l4:
    !mov [edi],bl
    !ud_l5:
    !inc edi
    !dec cl
    !jnz ud_l3
    !inc edx
    !sub edi,328
    !dec ch
    !jnz ud_l2
    !add edi,2568 
    !mov ecx,ebp
    !ud_l6:
    !inc esi
    !dec cl
    !jnz ud_l1
    !sub edi,2880
    !dec ch
    !jnz ud_l0
    !popad
    CatchSprite(0, *MZ700Display)
    DisplaySprite(0, 0, 0)
    FlipBuffers()
  EndIf
  Delay(2)
EndProcedure

Procedure MZ_Poke(addr.l, val.l)
  !mov edx,[p.v_addr]
  !mov eax,[p.v_val]
  !call mz_fp_call
  !jmp mz_fp_l1
  !mz_fp_call:
  !and edx,$ffff
  !mov ecx,edx
  !add edx,[p_RAM64K]
  !mov [edx],al
  !mov ah,ch
  !and ah,$f0
  !cmp ah,$d0
  !jne mz_fp_l0
  !and ecx,$7ff
  !mov edx,[p_RAM64K]
  !add edx,$10800
  !mov byte [edx],1
  !sub edx,$800
  !add edx,ecx
  !mov byte [edx],1
  !mz_fp_l0:
  !ret
  !mz_fp_l1:
EndProcedure

Macro MZ_FastPoke()
  !mov edx,[v_FastAddr]
  !mov eax,[v_FastVal]
  !call mz_fp_call
EndMacro

Procedure.l MZ_Peek(addr.l)
  !xor eax,eax
  !mov edx,[p.v_addr]
  !and edx,$ffff
  !add edx,[p_RAM64K]
  !mov al,[edx]
  ProcedureReturn
EndProcedure

Macro MZ_FastPeek()
  !xor eax,eax
  !mov edx,[v_FastAddr]
  !and edx,$ffff
  !add edx,[p_RAM64K]
  !mov al,[edx]
  !mov [p.v_val],eax
EndMacro

If OpenWindow(0, 0, 0, 320, 200, "MZ700Display", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If InitSprite() And OpenWindowedScreen(WindowID(0), 0, 0, 320, 200, #False, 0, 0)

    MZ_Poke($D000, $41)
    MZ_Poke($D800, $F2)
    MZ_Poke($D028, $97)
    MZ_Poke($D828, $F0)

    Repeat

      cnt = cnt + 1
      If cnt = 10
        FastVal = Random(7)
        For i = 80 To 799
          FastAddr = $D800 + i
          MZ_FastPoke()
        Next 
        cnt = 0
      EndIf

      UpdateDisplay()
  
      Event = WindowEvent()
    Until Event = #PB_Event_CloseWindow

  EndIf
EndIf

End

DataSection

  BMData:

    Data.b $42, $4D
    Data.l 64086, 0, 86, 40, 320, 200
    Data.w 1, 8
    Data.l 0, 64000, 0, 0, 8, 0
    Data.l $00000000 ; palette color 0
    Data.l $000000FF ; palette color 1
    Data.l $00FF0000 ; palette color 2
    Data.l $00FF00FF ; palette color 3
    Data.l $0000FF00 ; palette color 4
    Data.l $0000FFFF ; palette color 5
    Data.l $00FFFF00 ; palette color 6
    Data.l $00FFFFFF ; palette color 7

  CharROM:

    ; Character set 0

    Data.q $0000000000000000,$004242427E422418,$007C22223C22227C,$001C22404040221C,$0078242222222478,$007E40407840407E,$004040407840407E,$001C22424E40221C
    Data.q $004242427E424242,$001C08080808081C,$003844040404040E,$0042444870484442,$007E404040404040,$004242425A5A6642,$004242464A526242,$0018244242422418
    Data.q $004040407C42427C,$001A244A42422418,$004244487C42427C,$003C42023C40423C,$000808080808083E,$003C424242424242,$0018182424424242,$0042665A5A424242
    Data.q $0042422418244242,$000808081C222222,$007E40201804027E,$003E10103810120C,$0000000F08080808,$000000F808080808,$0808080F08080808,$000000FF08080808
    Data.q $003C42625A46423C,$003E080808281808,$007E40300C02423C,$003C42023C02423C,$0004047E24140C04,$003844020478407E,$003C42427C40201C,$001010100804427E
    Data.q $003C42423C42423C,$003804023E42423C,$000000007E000000,$0000007E007E0000,$1008080000080000,$0040201008040200,$0018180000000000,$1008080000000000
    Data.q $000000000000FF00,$4040404040404040,$FF80808080808080,$FF01010101010101,$00000000FF000000,$1010101010101010,$000000000000FFFF,$C0C0C0C0C0C0C0C0
    Data.q $0000FF0000000000,$0404040404040404,$FFFFFFFF00000000,$0F0F0F0F0F0F0F0F,$FF00000000000000,$0101010101010101,$FFFF000000000000,$0303030303030303
    Data.q $0010080804080810,$003E1C7F7F3E1C08,$0103070F1F3F7FFF,$FFFFFFFFFFFFFFFF,$00081C3E7F3E1C08,$0010207F20100000,$001C086B7F6B1C1C,$003C7E7E7E7E3C00
    Data.q $003C424242423C00,$001000100C02423C,$FFC381818181C3FF,$0808040300000000,$101020C000000000,$FFFEFCF8F0E0C080,$FF7F3F1F0F070301,$0000080000080000
    Data.q $000808082A1C0800,$000E18306030180E,$003C20202020203C,$00081C3E7F7F7F36,$003C04040404043C,$001E204C564A221C,$80C0E0F0F8FCFEFF,$0070180C060C1870
    Data.q $00081C2A08080800,$0002040810204000,$0004027F02040000,$0F0F0F0FF0F0F0F0,$0808080F00000000,$080808F800000000,$080808F808080808,$080808FF00000000
    Data.q $001414543E010000,$0008000008080808,$0000000000242424,$0024247E247E2424,$00081C0A1C281E08,$0046261008646200,$003A444A30484830,$0000000000100804
    Data.q $0004081010100804,$0020100808081020,$000008083E080800,$00082A1C3E1C2A08,$F0F0F0F00F0F0F0F,$8142241818244281,$00000000C0201010,$0000000003040808
    Data.q $00000000000000FF,$8080808080808080,$80808080808080FF,$01010101010101FF,$0000000000FF0000,$2020202020202020,$8040201008040201,$0102040810204080
    Data.q $000000FF00000000,$0808080808080808,$00000000FFFFFFFF,$F0F0F0F0F0F0F0F0,$00FF000000000000,$0202020202020202,$FFFFFF0000000000,$0707070707070707
    Data.q $0018181818181818,$003A443C04380000,$005C6242625C4040,$003C4240423C0000,$003A4642463A0202,$003C407E423C0000,$001010107C10120C,$3C023A46463A0000
    Data.q $00424242625C4040,$001C080808180008,$38440404040C0004,$0044685048444040,$001C080808080818,$0049494949760000,$00424242625C0000,$003C4242423C0000
    Data.q $40405C62625C0000,$02023A46463A0000,$00404040625C0000,$007C023C403E0000,$000C1210107C1010,$003A464242420000,$0018244242420000,$0036494949410000
    Data.q $0044281028440000,$3C023A4642420000,$007E2018047E0000,$003A443C04380024,$1008040201000000,$0000000080601C03,$00000000010638C0,$0810204080000000
    Data.q $030C30C000000000,$0000FF000000FF00,$4444444444444444,$4444FF444444FF44,$0000000000081020,$0000004C32000000,$11AA44AA11AA44AA,$C0300C0300000000
    Data.q $00000000C0300C03,$00000000030C30C0,$004C52424A444438,$001A262222002200,$001C22221C002200,$003C424242420042,$0042427E42241842,$0018244242241842
    Data.q $8080404040202010,$8040402020180601,$0102020404186080,$0101020202040408,$1020204040408080,$0106182020404080,$8060180404020201,$0804040202020101
    Data.q $0000000102040810,$031C608000000000,$C038060100000000,$0000008040201008,$0008101020101008,$080808FF08080808,$0000000000221408,$007E000000000000
    Data.q $003E00081C3E1C1C,$FFF7E3D5F7F7F7FF,$FFF7F7F7D5E3F7FF,$FFF7FB81FBF7FFFF,$FFEFDF81DFEFFFFF,$FFBDBDBD81BDBDBD,$FFE3DDBFBFBFDDE3,$0000245AFF7E2418
    Data.q $00E047427E4247E0,$417F4908082A3E22,$221408083E081C1C,$000011D2FCD21100,$0000884B3F4B8800,$1C1C083E08081422,$3C7EE7FFDBFF7E3C,$3C429981A581423C
    Data.q $55AA55AA55AA55AA,$050A050A050A050A,$50A050A050A050A0,$0000000055AA55AA,$55AA55AA00000000,$008040A050A854AA,$0102050A152A55AA,$55AA54A850A04080
    Data.q $552A150A05020100,$1010202040408080,$0101020204040808,$0000000000382838,$002A542A542A5400,$0808040402020101,$8080404020201010,$0022555454C8C000
    Data.q $02FF020000000000,$0207020202020202,$02FF020202020202,$0002058850200000,$010204C422110E00,$8844221188442211,$8040202344887000,$C4A4948F94A4C400
    Data.q $232529F129252300,$B898A8C0C0A09088,$8890A0C0C0B8B0A8,$8040201F10204080,$002424E724240000,$08083E00003E0808,$0402040810201008,$AA55AA55AA55AA55
    Data.q $0000000000000000,$0000000070707000,$0000000007070700,$0000000077777700,$7070700000000000,$7070700070707000,$7070700007070700,$7070700077777700
    Data.q $0707070000000000,$0707070070707000,$0707070007070700,$0707070077777700,$7777770000000000,$7777770070707000,$7777770007070700,$7777770077777700

    ; Character set 1

    Data.q $0000000000000000,$EEAABA82BABAC67C,$FC86BABA84BA86FC,$7EC2BEA0A0BEC27E,$F88CB6AAAAB68CF8,$FE82BE8888BE82FE,$E0A0A0B888BE82FE,$7E82BAAEA0BE827E
    Data.q $EEAAAABA82BAAAEE,$FE82EE2828EE82FE,$7CC6BAEA0A1B111F,$E6AAB48888B4AAE6,$FE82BEA0A0A0A0E0,$EEAAAABAAAAA82FE,$EEAAAAB2A28A9AEE,$7CC6BAAAAABAC67C
    Data.q $E0A0BC86BABA86FC,$7CC2B2AABABAC67C,$E6AAB484BABA86FC,$FC86FA7AC4BEC27E,$3828282828EE82FE,$7CC6BAAAAAAAAAEE,$102854AAAAAAAAEE,$FE82AAAABAAAAAEE
    Data.q $C6AA54282854AAC6,$382828284492AAEE,$FE825E2814FA82FE,$00007EFF90A04000,$00007EFF09050200,$009254387CD67C00,$00925438FE385492,$000000FE54380000
    Data.q $7C829AAAAAB2827C,$7C446C2828684838,$FE422E14CABA827C,$FC82FA2222FA82FC,$1CF682B65424140C,$FC86FA7A84BE82FE,$7C82BA82BCBE827E,$7050502814FA82FE
    Data.q $7C82BA827CBA827C,$FC82FA7A82BA827C,$003E22FAAABE88F8,$007C445F557D111F,$8142247EE7FF5A3C,$6624247EE7FF5A3C,$63363E777F2A1C08,$14363E777F2A1C08
    Data.q $6342FF7E5A3CA241,$C642FF7E5A3C4582,$0024422499BD5A00,$00C32418185AA581,$E724247EBD7E2400,$C34242247EBD7E24,$89DDFFD5ABFF5A3C,$2277FFD5ABFF5A3C
    Data.q $AAD5819981A5423C,$55AB819981A5423C,$3C7EFFFFE7664242,$1CFE3F0F0F3FFE1C,$424266E7FFFF7E3C,$387FFCF0F0FC7F38,$3C7EFFFFFFFF7E3C,$D6FE7C2828283810
    Data.q $03077EC77E070300,$081C1414143E7F6B,$C0E07EE37EE0C000,$4676763C183C0C3C,$7E5A5A3C183C243C,$626E6E3C183C303C,$6C24242424247E7E,$6624242424247E7E
    Data.q $3624242424247E7E,$3C3C7EFFB7F76322,$38FC3F0F3FFF6C38,$44C6EFEDFF7E3C3C,$1E3FFCF0FCFF361C,$3C3C7EFFBFFF7E3C,$3C7EFFFDFF7E3C3C,$1C3EFFFFFFFF361C
    Data.q $387CFFFFFFFF6C38,$3C3C183C3C3C3C18,$00007BFFFF7B0000,$183C3C3C3C183C3C,$0000DEFFFFDE0000,$3C3C283020206020,$000003070BFF4000,$040604040C143C3C
    Data.q $0000C0E0D0FF0200,$381010927C381010,$081031FF31100800,$1010387C92101038,$10088CFF8C081000,$0002044850607800,$0078605048040200,$001E060A12204000
    Data.q $004020120A061E00,$818181C3FF7E7E18,$1F7870F0F070781F,$187E7EFFC3818181,$F81E0E0F0F0E1EF8,$FF81BDA5A5ADA1BF,$FF01FD85A5BD81FF,$FD85B5A5A5BD81FF
    Data.q $FF81BDA5A1BF80FF,$FF007E003C001800,$0105155555150501,$0018003C007E00FF,$80A0A8AAAAA8A080,$3E1C08003E1C0800,$0011337733110000,$081C3E00081C3E00
    Data.q $0044667766440000,$000000E7A5E70000,$1038541010543810,$002442FF42240000,$7F0808081C22417F,$5555555555555555,$00FF00FF00FF00FF,$A542A50000A542A5
    Data.q $2442810000814224,$A0A0A0A0A09F80FF,$1115111511E501FF,$FFA0AFA0FF000000,$FF554141FF000000,$78303030FF809FA0,$1E0C0C0CFF01E111,$FF808F809580AA80
    Data.q $FF01E1015101A901,$08141010D5AB423C,$0000182424180000,$0018244242241800,$3C4281818181423C,$0000001818000000,$00003C3C3C3C0000,$007E7E7E7E7E7E00
    Data.q $3C429DA1A19D423C,$FFFFFFE7E7FFFFFF,$FFFFC3C3C3C3FFFF,$FF818181818181FF,$003C7EFF20203020,$3C4281FFFF81423C,$3C5A999999995A3C,$3C5A99FFFF995A3C
    Data.q $103854FEAAFE2800,$81808E8A4E40300F,$8101715172020CF0,$8180808E4040300F,$8101017102020CF0,$0F30404384888081,$F00C02C221110181,$0F30404087808081
    Data.q $F00C0202E1010181,$0F30404384838081,$F00C02C221C10181,$0F30404888878081,$F00C021211E10181,$7CFEFEFEFE541008,$3078783010080600,$004A2C6006345200
    Data.q $894A00C003005291,$FFFFFFFFF0E0C080,$FFC3C3FF02010000,$FFC3C3FF40800000,$FCFFFEFC1020C000,$FFFFFFFF0F070301,$0008141408281402,$FE4220102042FE00
    Data.q $3FFF7F3F08040300,$8648281010102000,$E7A5244242423C00,$00006C9282824400,$00006C92926C0000,$00006E90906C0200,$0010B05050101E00,$0010007C00100000
    Data.q $00515155555BF100,$FF9189A3C59189FF,$FFC3A59999A5C3FF,$925438EE38549200,$FF9999FFFF9999FF,$1010101010385492,$1038103810381038,$0000AAFFAA000000
    Data.q $7C0010107C101000,$427E427E427E427E,$00FF55555555FF00,$FF838CB0C0000000,$FFC1310D03000000,$FFFF7E3C00000000,$000000003C7EFFFF,$C0E0F0F0F0F0E0C0
    Data.q $03070F0F0F0F0703,$1F377FFF3F3F0C03,$FBFBF6EEDCB830C0,$0F030101040A0E0E,$FDFDFAF4F4F4747A,$3F607F6F46E44E04,$FC06FEF662277220,$070F1F101F1B313B
    Data.q $E0F0F808F8D88CDC,$30703E0E06070301,$0C0E7C7060E0C080,$8B7F370307060E1E,$D1FEECC0E0607078,$3F7FDF8C597B3301,$FCFEFB319ADECC80,$FF007F0F0F1F1F3F
    Data.q $FF00FEF0F0F8F8FC,$1F1F010204020100,$F8F8804020408000,$007F201F02020202,$00FE04F840404040,$0F0F1F3F7F737373,$F0F0F8FCFECECECE,$FF7F407F180F0F0F
    Data.q $FFFE02FE18F0F0F0,$F8444221214244F8,$FF050700000705FF,$FC868281818286FC,$0000807F40800000,$010101FF00000000,$000000FF01010101,$00000080808080FF
    Data.q $FF80808000000000,$080C0AF90A0C0800,$080C3AE93A0C0800,$008F8888FE48281F,$0F040209E640C040,$021F0A06E240C040,$0F010701EF40C040,$0F0107E14F20A040
    Data.q $FE806018061860C0,$7F01061860180601,$1F2A2A2A1D060100,$F3B1A9C911658F1B,$FE3E020718F0F74C,$FDF9818141319F7F,$9100418800400288,$1180044000880140
    Data.q $003079FFFD583000,$000C9EFFBF1A0C00,$0030F93FFD583000,$000C9FFCBF1A0C00,$381078FCBC682810,$BAFEBA3838AAEEBA,$BAEEAA3838BAFEBA,$E742FF9FFF42E700
    Data.q $E742FFF9FF42E700,$003E637F1CFC0000,$007CC6FE383F0000,$FF81A58181A581FF,$E7818100008181E7,$4020FE10FE080400,$1010101020242418,$1824240408080808
 
EndDataSection