vm: txt.width() and height() now return the actual console terminal width and height if possible.

This commit is contained in:
Irmen de Jong 2024-03-16 20:58:45 +01:00
parent 5a0524ff4d
commit 4db4a5f1b2
5 changed files with 89 additions and 44 deletions

View File

@ -6,11 +6,18 @@
txt {
sub width() -> ubyte {
return 80 ; just some chosen value for the 'width' of the console
%ir {{
syscall 62 (): r0.w
returnr.b r0
}}
}
sub height() -> ubyte {
return 30 ; just some chosen value for the 'height' of the console
%ir {{
syscall 62 (): r0.w
msig.b r1,r0
returnr.b r1
}}
}
sub clear_screen() {

View File

@ -1,9 +1,9 @@
TODO
====
vm textelite: after 1 galaxy jump: galaxy map shows wrong planet name if you first print local area map. local map is wrong too (secnd time it's okay).
fix ubyte width = text.width() text.width() gets removed as 'unused subroutine'
vm: textio.width and height should return the real console width and height.
vm textelite: after 1 galaxy jump: galaxy maps shows wrong planet name until you redraw them a second time. Current planet name changes when showing maps and asking planet i)nfo!
...

View File

@ -1,19 +1,16 @@
%import textio
%zeropage basicsafe
%option no_sysinit
main {
ubyte tw = text.width()
sub start() {
txt.print("hello, world!")
ubyte col = txt.get_column()
ubyte row = txt.get_row()
txt.row(10)
txt.print("row 10")
txt.column(2)
txt.print("col 2")
txt.plot(0, 18)
tw++
}
}
text {
sub width() -> ubyte {
cx16.r0++
return 80
}
}

View File

@ -8,7 +8,7 @@
; Prog8 adaptation of the Text-Elite galaxy system trading simulation engine.
; Original C-version obtained from: http://www.elitehomepage.org/text/index.htm
; Note: this program can be compiled for multiple target systems.
; Note: this program can be compiled for multiple target systems, including the virtual machine.
main {
@ -16,11 +16,13 @@ main {
const ubyte numforZaonce = 129
const ubyte numforDiso = 147
const ubyte numforRiedquat = 46
ubyte terminal_width
sub start() {
terminal_width = txt.width()
txt.lowercase()
txt.clear_screen()
txt.print("\n --- TextElite v1.2 ---\n")
txt.print("\n --- TextElite v1.3 ---\n")
planet.set_seed(0, 0)
galaxy.travel_to(1, numforLave)
@ -84,7 +86,7 @@ trader {
sub do_load() {
txt.print("\nLoading universe...")
if diskio.load(Savegame, &savedata)!=0 {
if diskio.load(Savegame, &savedata)==&savedata+sizeof(savedata) {
txt.print("ok\n")
} else {
txt.print("\ni/o error: ")
@ -493,16 +495,6 @@ galaxy {
ubyte py = planet.y
str current_name = " " ; 8 max
ubyte pn = 0
ubyte scaling_x = 8
ubyte scaling_y = 16
if local {
scaling_x = 2
scaling_y = 4
}
if txt.width() > 60 {
scaling_x /= 2
scaling_y /= 2
}
current_name = planet.name
init(number)
@ -533,10 +525,8 @@ galaxy {
tx = tx + 24 - px
ty = ty + 24 - py
}
tx /= scaling_x
ty /= scaling_y
ubyte sx = lsb(tx)
ubyte sy = lsb(ty)
ubyte sx = display_scale_x(tx)
ubyte sy = display_scale_y(ty)
ubyte char = '*'
if planet.number==current_planet
char = '%'
@ -555,11 +545,10 @@ galaxy {
if not local
print_planet_details(current_name, home_sx, home_sy, home_distance)
if txt.width() < 80
txt.plot(0,20)
if local
txt.plot(0, display_scale_y(64) + 4)
else
txt.plot(0,36)
txt.plot(0, display_scale_y(256) + 4 as ubyte)
travel_to(number, current_planet)
sub print_planet_details(str name, ubyte screenx, ubyte screeny, ubyte d) {
@ -571,6 +560,28 @@ galaxy {
txt.print(" LY")
}
}
sub display_scale_x(uword x) -> ubyte {
if main.terminal_width > 64 {
if local
return x as ubyte
return x/4 as ubyte
}
if local
return x/2 as ubyte
return x/8 as ubyte
}
sub display_scale_y(uword y) -> ubyte {
if main.terminal_width > 64 {
if local
return y/2 as ubyte
return y/8 as ubyte
}
if local
return y/4 as ubyte
return y/16 as ubyte
}
}
ubyte pn_pair1

View File

@ -72,6 +72,7 @@ SYSCALLS:
59 = delete
60 = rename
61 = directory
62 = getconsolesize
*/
enum class Syscall {
@ -136,7 +137,8 @@ enum class Syscall {
SAVE,
DELETE,
RENAME,
DIRECTORY
DIRECTORY,
GETGONSOLESIZE
;
companion object {
@ -644,9 +646,9 @@ object SysCalls {
for (i in 0..<data.size - 2) {
vm.memory.setUB(addr + i, data[i + 2].toUByte())
}
vm.registers.setUW(0, (addr + data.size - 2).toUShort())
returnValue(callspec.returns!!, (addr + data.size - 2).toUShort(), vm)
} else {
vm.registers.setUW(0, 0u)
returnValue(callspec.returns!!, 0u, vm)
}
}
Syscall.LOAD_RAW -> {
@ -658,9 +660,9 @@ object SysCalls {
for (i in 0..<data.size) {
vm.memory.setUB(addr + i, data[i].toUByte())
}
vm.registers.setUW(0, (addr + data.size).toUShort())
returnValue(callspec.returns!!, (addr + data.size).toUShort(), vm)
} else {
vm.registers.setUW(0, 0u)
returnValue(callspec.returns!!, 0u, vm)
}
}
Syscall.SAVE -> {
@ -686,10 +688,10 @@ object SysCalls {
}
val filename = vm.memory.getString((filenamePtr as UShort).toInt())
if (File(filename).exists())
vm.registers.setUB(0, 0u)
returnValue(callspec.returns!!, 0u, vm)
else {
File(filename).writeBytes(data)
vm.registers.setUB(0, 1u)
returnValue(callspec.returns!!, 1u, vm)
}
}
Syscall.DELETE -> {
@ -710,7 +712,35 @@ object SysCalls {
directory.listDirectoryEntries().sorted().forEach {
println("${it.toFile().length()}\t${it.normalize()}")
}
vm.registers.setUB(0, 1u)
returnValue(callspec.returns!!, 1u, vm)
}
Syscall.GETGONSOLESIZE -> {
// no arguments
if(System.console()==null) {
return returnValue(callspec.returns!!, 30*256 + 80, vm) // just return some defaults in this case 80*30
}
val linesS = System.getenv("LINES")
val columnsS = System.getenv("COLUMNS")
if(linesS!=null && columnsS!=null) {
val lines = linesS.toInt()
val columns = columnsS.toInt()
return returnValue(callspec.returns!!, lines*256 + columns, vm)
}
try {
val process = ProcessBuilder("tput", "cols", "lines").inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE).start()
val result=process.waitFor()
if (result == 0) {
val response = process.inputStream.bufferedReader().lineSequence().iterator()
val width = response.next().toInt()
val height = response.next().toInt()
return returnValue(callspec.returns!!, height*256 + width, vm)
}
} catch (x: Exception) {
// dunno what happened...
}
return returnValue(callspec.returns!!, 30*256 + 80, vm) // just return some defaults in this case 80*30
}
}
}