Author Topic: How to pass a string array to a procedure  (Read 998 times)

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11552
  • Assembler is fun ;-)
    • MasmBasic
How to pass a string array to a procedure
« on: February 18, 2021, 11:44:31 AM »
The new _Passed$ macro allows to pass an entire string array to a procedure, as if it was a "local" array. Below, wi$() resp. wx$() push the array ID on the stack, with invoke PrintStringArray, wi$(), 10 (the second argument, #rows to be printed, is not really needed here). The PrintStringArray procedure receives the ID and has thus access to most array functions, e.g. Let _Passed$(arrID, ecx)=Str$("new string #%i", ecx); Insert and Delete are also available, of course.

The example prints the first ten lines of two important Masm32 SDK files.

include \masm32\MasmBasic\MasmBasic.inc
.code
PrintStringArray proc arrID, rows       ; you can pass it any string array
  xor ecx, ecx
  .Repeat
        Print Str$("\nRow #%i\t", ecx), _Passed$(arrID, ecx)
        inc ecx
  .Until ecx>=rows
  ret
PrintStringArray endp

  Init                         ; select and hit F6 to test this example
  Recall "\Masm32\include\Windows.inc", wi$()
  Recall "\Masm32\include\WinExtra.inc", wx$()
  Print "First 10 lines of Windows.inc:"
  invoke PrintStringArray, wi$(), 10
  Print CrLf$, "First 10 lines of WinExtra.inc:"
  invoke PrintStringArray, wx$(), 10
EndOfCode
Rem    - _Passed$(id, args) allows most of the operations of normal string arrays
        - first argument is the ID of the array, as passed on the stack; all other arguments as usual


Requires MasmBasic 18 February 2021

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11552
  • Assembler is fun ;-)
    • MasmBasic
Re: How to pass a string array to a procedure
« Reply #1 on: February 18, 2021, 08:34:03 PM »
Another application of _Passed$() is the use of different string arrays to switch languages (project attached):

Code: [Select]
GuiParas equ "Plotting data", x400, y60, w800, h600, col white, b RgbCol(0, 0, 0)
include \masm32\MasmBasic\Res\MbGui.asm
  MakePen hPen, RgbCol(255, 160, 160)
  StringToArray 99, rk() As REAL4 ; fill a REAL4 data array; 99 is the resource ID for PlotData.tab; see also ArrayRead
  SetAxisX "Вы можете использовать другой шрифт для абсциссы", s 0, d 0.01/10, grid 1, format "%2f x" ; s=start value, d=difference between gridlines
  SetAxisY "The ordinate can be as long as you want it to be", s -1, d 0.02/5, grid 1, format "%2f y", penx hPen
  ArraySet Leg_EN$()="Series 1", "Series 2" ; create a string array for the legend
  ArraySet Leg_CN$()="系列1", "系列1"  ; Chinese version
  ArraySet title$()="Plotting data is easy!!", "绘制数据很简单!"
  SetGlobals language, idLeg

Event Key
  xor language, 1 ; toggle language
  GuiRefresh ; trigger WM_PAINT

Event Paint
  mov idLeg, Leg_EN$()
  mov edx, language
  add idLeg, edx
  Legend _Passed$(idLeg), ll ; ll=place legend in lower left corner
  ArrayPlotValues "%2f Volt", 8, -12 ; format$, dx & dy positions
  ArrayPlot rk(XY), RgbCol(100, 255, 255, 0), lines=8, 03040411h ; left+bottom set; draw the array with 8px transparent red lines (try bars=30)
  ArrayPlotValues 0           ; vvv alpha not ignored for dots, ok
  ArrayPlot rk(XY), RgbCol(255, 255, 255, 0), 5 ; plot the array with 5px red dots
  GuiTextBox 250, 95.0-75, 250, auto, "Plotting a dataset is really easy with MasmBasic - hit any key to change language", fcol Black, bcol RgbCol(255, 255, 192), font 24
  ArrayPlot exit, 0200002032# title$(language), fcol Red ; finish with a title, xxxxyyyyfontsize
EndOfCode

LiaoMi

  • Member
  • ****
  • Posts: 922
Re: How to pass a string array to a procedure
« Reply #2 on: February 19, 2021, 01:02:38 AM »
Another application of _Passed$() is the use of different string arrays to switch languages (project attached):

Code: [Select]
GuiParas equ "Plotting data", x400, y60, w800, h600, col white, b RgbCol(0, 0, 0)
include \masm32\MasmBasic\Res\MbGui.asm
  MakePen hPen, RgbCol(255, 160, 160)
  StringToArray 99, rk() As REAL4 ; fill a REAL4 data array; 99 is the resource ID for PlotData.tab; see also ArrayRead
  SetAxisX "Вы можете использовать другой шрифт для абсциссы", s 0, d 0.01/10, grid 1, format "%2f x" ; s=start value, d=difference between gridlines
  SetAxisY "The ordinate can be as long as you want it to be", s -1, d 0.02/5, grid 1, format "%2f y", penx hPen
  ArraySet Leg_EN$()="Series 1", "Series 2" ; create a string array for the legend
  ArraySet Leg_CN$()="系列1", "系列1"  ; Chinese version
  ArraySet title$()="Plotting data is easy!!", "绘制数据很简单!"
  SetGlobals language, idLeg

Event Key
  xor language, 1 ; toggle language
  GuiRefresh ; trigger WM_PAINT

Event Paint
  mov idLeg, Leg_EN$()
  mov edx, language
  add idLeg, edx
  Legend _Passed$(idLeg), ll ; ll=place legend in lower left corner
  ArrayPlotValues "%2f Volt", 8, -12 ; format$, dx & dy positions
  ArrayPlot rk(XY), RgbCol(100, 255, 255, 0), lines=8, 03040411h ; left+bottom set; draw the array with 8px transparent red lines (try bars=30)
  ArrayPlotValues 0           ; vvv alpha not ignored for dots, ok
  ArrayPlot rk(XY), RgbCol(255, 255, 255, 0), 5 ; plot the array with 5px red dots
  GuiTextBox 250, 95.0-75, 250, auto, "Plotting a dataset is really easy with MasmBasic - hit any key to change language", fcol Black, bcol RgbCol(255, 255, 192), font 24
  ArrayPlot exit, 0200002032# title$(language), fcol Red ; finish with a title, xxxxyyyyfontsize
EndOfCode


Hi jj2007,

should the curved lines in the picture look like this?


jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11552
  • Assembler is fun ;-)
    • MasmBasic
Re: How to pass a string array to a procedure
« Reply #3 on: February 19, 2021, 03:59:28 AM »
Oops, you are right, thanks :thumbsup:

That's actually funny, as I can't see a good reason why a line should behave like this. Will have to dig very deep into the GdiPlus-based proc where this happens. Actually, if my nights are not filled with bug chasing, it can be boring :tongue:

LiaoMi

  • Member
  • ****
  • Posts: 922
Re: How to pass a string array to a procedure
« Reply #4 on: March 03, 2021, 05:03:55 AM »
Oops, you are right, thanks :thumbsup:

That's actually funny, as I can't see a good reason why a line should behave like this. Will have to dig very deep into the GdiPlus-based proc where this happens. Actually, if my nights are not filled with bug chasing, it can be boring :tongue:

Hi jj2007,

did you find the error?  :rolleyes:

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11552
  • Assembler is fun ;-)
    • MasmBasic
Re: How to pass a string array to a procedure
« Reply #5 on: March 03, 2021, 10:00:20 AM »
did you find the error?  :rolleyes:

Yessss... but I am still working on other stuff, so it will go online in a few days.

before:
Code: [Select]
.if useYaxis
mov eax, APs.apRectL.left ; left+2
inc eax
inc eax
invoke MoveToEx, APs.apMemDC, eax, APs.apRectL.top, 0 ; draw Y-axis vertical black line
apLineTo APs.apRectL.left, APs.apRectL.bottom
.endif

after:
Code: [Select]
.if useYaxis
mov eax, APs.apRectL.left ; left+2
inc eax
inc eax
push eax ; adjusted x
invoke MoveToEx, APs.apMemDC, eax, APs.apRectL.top, 0 ; draw Y-axis vertical black line
push APs.apRectL.bottom
call _apLineTo ; left+2 already on stack
.endif