-- -- demo\rosetta\Wireworld.exw -- ========================== -- -- Invoke with file to read or let it read the one below (if compiled assumes source is in the same directory) -- -- Note that tabs in description files are not supported - where necessary spaces can be replaced with _ chars. -- (tab chars in text files should technically always represent (to-next) 8 spaces, but not many editors respect -- that, and instead assume the file will only ever be read by the same program/with matching settings. ) -- (see also demo\edix\src\tabs.e\ExpandTabs() for what you'd need if you knew what tab chars really meant.) -- /* -- default description: tH......... .___. ___... .___. Ht.. ...... */ sequence lines, counts integer longest function valid_line(string line, integer l=0) if length(line)=0 then return 0 end if for i=1 to length(line) do integer ch = line[i] if not find(ch," _.tH") then if l and ch='\t' then -- as above printf(1,"error: tab char on line %d\n",{l}) {} = wait_key() abort(0) end if return 0 end if end for return 1 end function procedure load_desc() string filename = substitute(command_line()[$],".exe",".exw") integer fn = open(filename,"r") if fn=-1 then printf(1,"error opening %s\n",{filename}) {} = wait_key() abort(0) end if sequence text = get_text(fn,GT_LF_STRIPPED) close(fn) lines = {} for i=1 to length(text) do string line = text[i] if valid_line(line) then lines = {line} longest = length(line) for j=i+1 to length(text) do line = text[j] if not valid_line(line,j) then exit end if lines = append(lines,line) if longest=1 and cy<=length(lines) and cx>=1 and cx<=length(lines[cy]) and lines[cy][cx]='H' then count += 1 end if end for counts[y][x] = (count=1 or count=2) end if end for end for end procedure include pGUI.e Ihandle dlg, canvas, timer cdCanvas cddbuffer, cdcanvas function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/) integer {w, h} = IupGetIntInt(canvas, "DRAWSIZE") integer dx = floor(w/(longest+2)) integer dy = floor(h/(length(lines)+2)) cdCanvasActivate(cddbuffer) cdCanvasClear(cddbuffer) set_counts() for y=1 to length(lines) do for x=1 to length(lines[y]) do integer c = lines[y][x], colour if find(c," _") then colour = CD_BLACK elsif c='.' then colour = CD_YELLOW if counts[y][x] then lines[y][x] = 'H' end if elsif c='H' then colour = CD_BLUE lines[y][x] = 't' elsif c='t' then colour = CD_RED lines[y][x] = '.' end if cdCanvasSetForeground(cddbuffer, colour) cdCanvasBox(cddbuffer,x*dx,x*dx+dx,h-y*dy,h-(y*dy+dy)) end for end for cdCanvasFlush(cddbuffer) return IUP_DEFAULT end function function timer_cb(Ihandle /*ih*/) IupUpdate(canvas) return IUP_IGNORE end function function map_cb(Ihandle ih) cdcanvas = cdCreateCanvas(CD_IUP, ih) cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas) cdCanvasSetBackground(cddbuffer, CD_BLACK) return IUP_DEFAULT end function function esc_close(Ihandle /*ih*/, atom c) if c=K_ESC then return IUP_CLOSE end if return IUP_CONTINUE end function procedure main() load_desc() IupOpen() canvas = IupCanvas(NULL) IupSetAttribute(canvas, "RASTERSIZE", "300x180") IupSetCallback(canvas, "MAP_CB", Icallback("map_cb")) IupSetCallback(canvas, "ACTION", Icallback("redraw_cb")) timer = IupTimer(Icallback("timer_cb"), 500) dlg = IupDialog(canvas) IupSetAttribute(dlg, "TITLE", "Wireworld") IupSetCallback(dlg, "K_ANY", Icallback("esc_close")) IupShow(dlg) IupSetAttribute(canvas, "RASTERSIZE", NULL) IupMainLoop() IupClose() end procedure main()