The Return of Viking Chess (Hnefatafl)
Re: The Return of Viking Chess (Hnefatafl)
You know, you could have a 'teacher' mode that shows hints to the player on what he should play/should avoid, perhaps drawing small numbers in the cells indicating recommended/advised locations, so players can learn to play
- barnsey123
- Flight Lieutenant
- Posts: 379
- Joined: Fri Mar 18, 2011 10:04 am
- Location: Birmingham
Re: The Return of Viking Chess (Hnefatafl)
500 bytes left...Dbug wrote:You know, you could have a 'teacher' mode that shows hints to the player on what he should play/should avoid, perhaps drawing small numbers in the cells indicating recommended/advised locations, so players can learn to play
Maybe in the disk version (TBD if I ever can) a menu in the loader will allow you to select three different programs "Play as King", "Play as Attackers" and "Tutorial"...here's hoping anyway...
Re: The Return of Viking Chess (Hnefatafl)
If you have all the code on SVN, I can take a look at the memory map and see if I can get the memory usage downbarnsey123 wrote:500 bytes left...Dbug wrote:You know, you could have a 'teacher' mode that shows hints to the player on what he should play/should avoid, perhaps drawing small numbers in the cells indicating recommended/advised locations, so players can learn to play
Maybe in the disk version (TBD if I ever can) a menu in the loader will allow you to select three different programs "Play as King", "Play as Attackers" and "Tutorial"...here's hoping anyway...
- barnsey123
- Flight Lieutenant
- Posts: 379
- Joined: Fri Mar 18, 2011 10:04 am
- Location: Birmingham
Re: The Return of Viking Chess (Hnefatafl)
in v0.088 I've reduced the size of the prog from 37222 bytes to 36914 (saving about 300 bytes). This was a mixture of improving some inefficient routines and some loop unrolling.Dbug wrote:If you have all the code on SVN, I can take a look at the memory map and see if I can get the memory usage down
All src is on SVN so yes, please take a look but only if you've got time.
There are two areas which definitely need changing, one is a clumsy text printing routine called "chasm2" in draw.s (see below), I've tried changing this with "chasm3" (commented out for now) which compiles OK but I get no text on the hires screen. The problem with chasm2 is I have to hardcode the locations for the start of the char. I just can't get this to work when loading a variable (see chasm3). Have tried all manner of things (either it doesn't compile, or I get nothing or I get garbage)
A while ago Chema mentioned using self-modifying code to achieve this. I read up on it and Voodoo made more sense, I just don't get it...
Code: Select all
_chasm2
.(
lda _deadcurset+0 ; deadcurset is a hires screen location
sta tmp1+0
lda _deadcurset+1
sta tmp1+1
ldx #0
loop
lda _textchar ; load the char id no into accumulator
cmp #40 ; is it an ( - DEFENDER
beq chasmDEF
cmp #41 ; is it an ) - ATTACKER
beq chasmATT
cmp #65 ; is it an A?
beq chasmA
cmp #66 ; B?
beq chasmB
cmp #68 ; D?
beq chasmD
cmp #69 ; E?
beq chasmE
cmp #70 ; F?
beq chasmF
cmp #71 ; G?
beq chasmG
cmp #73 ; I?
beq chasmI
cmp #75 ; K?
beq chasmK
cmp #76 ; L?
beq chasmL
cmp #79 ; O?
beq chasmO
cmp #82 ; R?
beq chasmR
cmp #83 ; S?
beq chasmS
cmp #84 ; T?
beq chasmT
cmp #85 ; U?
beq chasmU
cmp #90 ; Z?
beq chasmZ
lda $9900,x ; else print a space
chasmx2
ldy #0
sta (tmp1),y
jsr _Add40
inx
cpx #7
bcc loop
rts
chasmDEF
lda $9940,x
jmp chasmx2
chasmATT
lda $9948,x
jmp chasmx2
chasmA
lda $9A08,x
jmp chasmx2
chasmB
lda $9A10,x
jmp chasmx2
chasmD
lda $9A20,x
jmp chasmx2
chasmE
lda $9A28,x
jmp chasmx2
chasmF
lda $9A30,x
jmp chasmx2
chasmG
lda $9A38,x
jmp chasmx2
chasmI
lda $9A48,x
jmp chasmx2
chasmK
lda $9A58,x
jmp chasmx2
chasmL
lda $9A60,x
jmp chasmx2
chasmO
lda $9A78,x
jmp chasmx2
chasmR
lda $9A90,x
jmp chasmx2
chasmS
lda $9A98,x
jmp chasmx2
chasmT
lda $9AA0,x
jmp chasmx2
chasmU
lda $9AA8,x
jmp chasmx2
chasmZ
lda $9AD0,x
jmp chasmx2
.)
;_chasm3
;.(
; lda _deadcurset+0
; sta tmp1+0
; lda _deadcurset+1
; sta tmp1+1
; ldx #0
;loop
; lda _someint,x ; where someint represents say $9AD0 (for the char Z)
; ldy #0
; sta (tmp1),y
; jsr _Add40
; inx
; cpx #7
; bcc loop
; rts
;.)
A problem with making months-old code more efficient is it can introduce problems (I've been caught out before) for example: pseudocode:
Code: Select all
if (a==1) someroutine()
if (b==1) someroutine()
if (c==1) someroutine()
Code: Select all
if ( (a==1) || (b==1) || (c==1)) someroutine()
This should result in shorter compiled code but - depending on what someroutine() does it may not be correct.
I may want someroutine() to run up to 3 times depending on the values a,b,c (not just once).
It's easy to get caught out...as they say: "logic is a method of arriving at the wrong answer with confidence..."
Re: The Return of Viking Chess (Hnefatafl)
There's a number of places where you suffer the 'death by a thousand cuts' problem.
For example you have:
the incroute function is implemented in assembler this way:
Since '_route' is a normal variable the code will use absolute addressing, so the lenght of the function is 4 bytes (inc+2+rts)
The problem is that if you look at the generated code (%osdk%\tmp\linked.s) you will see that the compiler generated that:
So basically for each call to this 4 bytes routine you get a 5 bytes function call, while if the 'inc _route' was directly inlined it would only take 3 bytes in total.
DrawPictureTiles() is a very simple function, yet it uses 16 bytes because the compiler kind of suck:
could be rewritten as:
Which is 3 bytes shorter, but the problem is compounded by the fact that the compiler does not really generate code that uses the registers efficiently. A more efficient way would have been to have _drawtile takes two parameters (say X and Y) and have the code do:
Which reduces the size globally because a function is called more than once, so for each additional call you reduce the size by two sta, which is 4 bytes here.
The whole 'chasmx' dispatcher can probably be reduced in size by replacing all the 'jmp chasmx2' by 'rts' and changing the original call to the dispatcher by a jsr followed by the 'chasmx2' function.
I can do some fixes, just not today.
So suggestions:
- Check the whole linked.s file, it gives a good overview
- Double check with the 'osdk_showmap.bat' to see what takes size
For example you have:
Code: Select all
void checkincroute(){
if ( players[a][b] == 0 ) incroute();
if ( (a == 5) && (b == 5) && (players[a][b] == 4)) incroute();
if (( piecetype == 3 )&&(tiles[a][b] == 4 )) incroute(); // KING: corner square OK
}
Code: Select all
_incroute
inc _route
rts
The problem is that if you look at the generated code (%osdk%\tmp\linked.s) you will see that the compiler generated that:
Code: Select all
ldy #0
jsr _incroute
DrawPictureTiles() is a very simple function, yet it uses 16 bytes because the compiler kind of suck:
Code: Select all
_DrawPictureTiles
lda #<(_PictureTiles)
sta _ptr_graph
lda #>(_PictureTiles)
sta _ptr_graph+1
ldy #0
jsr _drawtile
rts
Code: Select all
_DrawPictureTiles
lda #<(_PictureTiles)
sta _ptr_graph
lda #>(_PictureTiles)
sta _ptr_graph+1
jmp _drawtile
Code: Select all
_DrawPictureTiles
ldx #<(_PictureTiles)
ldy #>(_PictureTiles)
jmp _drawtile
The whole 'chasmx' dispatcher can probably be reduced in size by replacing all the 'jmp chasmx2' by 'rts' and changing the original call to the dispatcher by a jsr followed by the 'chasmx2' function.
I can do some fixes, just not today.
So suggestions:
- Check the whole linked.s file, it gives a good overview
- Double check with the 'osdk_showmap.bat' to see what takes size
- barnsey123
- Flight Lieutenant
- Posts: 379
- Joined: Fri Mar 18, 2011 10:04 am
- Location: Birmingham
Re: The Return of Viking Chess (Hnefatafl)
OK Dbug,
many thanks for that. I'm not sure I understand it all (still weak with ASM) but I've burnt through the C code and made some more improvements. Now down to 36732 so I have about 1K spare at present.
I'm going to make some more changes to slim it down further (I have some more routines to squeeze in and these will improve the AI). I must say I'm enjoying the play testing more as it's making smarter moves (but there's room for improvement...).
many thanks for that. I'm not sure I understand it all (still weak with ASM) but I've burnt through the C code and made some more improvements. Now down to 36732 so I have about 1K spare at present.
I'm going to make some more changes to slim it down further (I have some more routines to squeeze in and these will improve the AI). I must say I'm enjoying the play testing more as it's making smarter moves (but there's room for improvement...).
- barnsey123
- Flight Lieutenant
- Posts: 379
- Joined: Fri Mar 18, 2011 10:04 am
- Location: Birmingham
Re: The Return of Viking Chess (Hnefatafl)
v0.090
More memory reductions, some improvements and a bug fix...the circled piece is the one selected for a possible move...note central square is not highlighted (it is possible to traverse it but not occupy it)
Previously when pressing "P" for Possible Moves it still looked possible for a non-king piece to occupy the central square (in fact, you couldn't do this but it looked like you could). This is now fixed and so it should be less confusing for a new player.
There used to be a "compass" graphic printed instead of the new "red box". So I've saved some memory both in the code and in the graphics data. As a bonus it also looks better.
If I can fit it in, I'll print a skull in dangerous locations...(but only in SAGA mode)
More memory reductions, some improvements and a bug fix...the circled piece is the one selected for a possible move...note central square is not highlighted (it is possible to traverse it but not occupy it)
Previously when pressing "P" for Possible Moves it still looked possible for a non-king piece to occupy the central square (in fact, you couldn't do this but it looked like you could). This is now fixed and so it should be less confusing for a new player.
There used to be a "compass" graphic printed instead of the new "red box". So I've saved some memory both in the code and in the graphics data. As a bonus it also looks better.
If I can fit it in, I'll print a skull in dangerous locations...(but only in SAGA mode)
Re: The Return of Viking Chess (Hnefatafl)
I wanted to do some changes, but then I noticed there was a bunch of problems:
- the program does not switch to hires so all the screen is garbled
- when using the cursor to select the position that makes the screen to scroll
did I do something wrong? Is there something fancy to do with the 'loader' project?
- the program does not switch to hires so all the screen is garbled
- when using the cursor to select the position that makes the screen to scroll
did I do something wrong? Is there something fancy to do with the 'loader' project?
- barnsey123
- Flight Lieutenant
- Posts: 379
- Joined: Fri Mar 18, 2011 10:04 am
- Location: Birmingham
Re: The Return of Viking Chess (Hnefatafl)
Yes, the loader has to be loaded first (it sets hires and changes the font)Dbug wrote:I wanted to do some changes, but then I noticed there was a bunch of problems:
- the program does not switch to hires so all the screen is garbled
- when using the cursor to select the position that makes the screen to scroll
did I do something wrong? Is there something fancy to do with the 'loader' project?
This will display the loading picture and some text. When the picture turns red you have to type (blindly): CLOAD"VIKING.TAP"
IMPORTANT: Ensure VIKING.tap (main prog) is in the oricutron tapes directory (I have a bat file that copies the tap file there after building it)
- barnsey123
- Flight Lieutenant
- Posts: 379
- Joined: Fri Mar 18, 2011 10:04 am
- Location: Birmingham
Re: The Return of Viking Chess (Hnefatafl)
v0.91
Fixed MAJOR bug in findpiece() routine. It's a "don't take a piece if it allows the king to escape" sort of thing.
It's not 100% fixed (about 90%) but I know what to do...
Fixed MAJOR bug in findpiece() routine. It's a "don't take a piece if it allows the king to escape" sort of thing.
It's not 100% fixed (about 90%) but I know what to do...
Re: The Return of Viking Chess (Hnefatafl)
By the way, if you are interested there's an easy way to get almost 1 kilobyte of free memory: Instead of using standard text, use alternate text, and overwrite the standard text with whatever you want
Re: The Return of Viking Chess (Hnefatafl)
Also, if you change SET OSDKADDR=$500 to say $400 in your osdk_config.bat, you get 256 more bytes available.
- barnsey123
- Flight Lieutenant
- Posts: 379
- Joined: Fri Mar 18, 2011 10:04 am
- Location: Birmingham
Re: The Return of Viking Chess (Hnefatafl)
Deffo interested but how would that work? I still have to load the new font data of size X. Presumably the method of loading would still be the same...so...I'm confused...Dbug wrote:By the way, if you are interested there's an easy way to get almost 1 kilobyte of free memory: Instead of using standard text, use alternate text, and overwrite the standard text with whatever you want
- barnsey123
- Flight Lieutenant
- Posts: 379
- Joined: Fri Mar 18, 2011 10:04 am
- Location: Birmingham
Re: The Return of Viking Chess (Hnefatafl)
Again confused...if I can set it to $400 why not $100 or less? I didn't get the whole Osdkaddr thing anyway...what is its purpose?Dbug wrote:Also, if you change SET OSDKADDR=$500 to say $400 in your osdk_config.bat, you get 256 more bytes available.
Re: The Return of Viking Chess (Hnefatafl)
I'm assuming that you loaded the font in your Loader, so it's not present when the main code is present.barnsey123 wrote:Deffo interested but how would that work? I still have to load the new font data of size X. Presumably the method of loading would still be the same...so...I'm confused...Dbug wrote:By the way, if you are interested there's an easy way to get almost 1 kilobyte of free memory: Instead of using standard text, use alternate text, and overwrite the standard text with whatever you want
So assuming your loader is copying the font to the address $B400/$9800, which is where the STANDARD font is located.
Instead you could copy the font data to the address $B800/$9C00, which is where the ALTERNATE (the one shown in LORES 1 mode) is located.
That means that the whole standard charset area is available for your own code or data, of course if you try to print any text it's going to be garbled, but it's just a matter of using the attribute 9 at the start of the line, and there you go: You are using the second charset instead.
This defines the address at which your code is assembled and loaded.barnsey123 wrote:Again confused...if I can set it to $400 why not $100 or less? I didn't get the whole Osdkaddr thing anyway...what is its purpose?
By default in the OSDK I set it to $500 because that makes the code compatible with the system DOS.
Since you are first releasing a floppy version, you can assemble as low as $400, that would trash the DOS if you tried to load the game from disk, but that gives you 256 more bytes.
You can't go lower, because the page 3 is used for I/O, page 1 is the stack, page 0 is where all your temporaries are stored.
Technically you can use the page 2 for whatever you want, but for that you need to not use the ROM at all, else things will crash badly