aboutsummaryrefslogtreecommitdiff
path: root/cube.c (follow)
Commit message (Collapse)AuthorAge
* Add method for frontends to query the backend's cursor location.Franklin Wei2020-12-07
| | | | | | | | | | | | | | | | The Rockbox frontend allows games to be displayed in a "zoomed-in" state targets with small displays. Currently we use a modal interface -- a "viewing" mode in which the cursor keys are used to pan around the rendered bitmap; and an "interaction" mode that actually sends keys to the game. This commit adds a midend_get_cursor_location() function to allow the frontend to retrieve the backend's cursor location or other "region of interest" -- such as the player location in Cube or Inertia. With this information, the Rockbox frontend can now intelligently follow the cursor around in the zoomed-in state, eliminating the need for a modal interface.
* Use C99 bool within source modules.Simon Tatham2018-11-13
| | | | | | | | | | This is the main bulk of this boolification work, but although it's making the largest actual change, it should also be the least disruptive to anyone interacting with this code base downstream of me, because it doesn't modify any interface between modules: all the inter-module APIs were updated one by one in the previous commits. This just cleans up the code within each individual source file to use bool in place of int where I think that makes things clearer.
* Replace TRUE/FALSE with C99 true/false throughout.Simon Tatham2018-11-13
| | | | | | This commit removes the old #defines of TRUE and FALSE from puzzles.h, and does a mechanical search-and-replace throughout the code to replace them with the C99 standard lowercase spellings.
* Adopt C99 bool in the game backend API.Simon Tatham2018-11-13
| | | | | | | | | | | encode_params, validate_params and new_desc now take a bool parameter; fetch_preset, can_format_as_text_now and timing_state all return bool; and the data fields is_timed, wants_statusbar and can_* are all bool. All of those were previously typed as int, but semantically boolean. This commit changes the API declarations in puzzles.h, updates all the games to match (including the unfinisheds), and updates the developer docs as well.
* cube.c: Prohibit unsolvable single row/column gameMichael Quevillon2018-09-13
| | | | | | For cube games, the minimum for any dimension should be 2, as there is no net of the cube that is only one row/column. The previous logic would permit a 1x7 game (for example) that could never be solved.
* Add a request_keys() function with a midend wrapper.Franklin Wei2018-04-22
| | | | | | | | This function gives the front end a way to find out what keys the back end requires; and as such it is mostly useful for ports without a keyboard. It is based on changes originally found in Chris Boyle's Android port, though some modifications were needed to make it more flexible.
* Make the code base clean under -Wwrite-strings.Simon Tatham2017-10-01
| | | | | I've also added that warning option and -Werror to the build script, so that I'll find out if I break this property in future.
* Return error messages as 'const char *', not 'char *'.Simon Tatham2017-10-01
| | | | | They're never dynamically allocated, and are almost always string literals, so const is more appropriate.
* Use a proper union in struct config_item.Simon Tatham2017-10-01
| | | | | | This allows me to use different types for the mutable, dynamically allocated string value in a C_STRING control and the fixed constant list of option names in a C_CHOICES.
* Rework the preset menu system to permit submenus.Simon Tatham2017-04-26
| | | | | | | | | | | | | | | | | | | | To do this, I've completely replaced the API between mid-end and front end, so any downstream front end maintainers will have to do some rewriting of their own (sorry). I've done the necessary work in all five of the front ends I keep in-tree here - Windows, GTK, OS X, Javascript/Emscripten, and Java/NestedVM - and I've done it in various different styles (as each front end found most convenient), so that should provide a variety of sample code to show downstreams how, if they should need it. I've left in the old puzzle back-end API function to return a flat list of presets, so for the moment, all the puzzle backends are unchanged apart from an extra null pointer appearing in their top-level game structure. In a future commit I'll actually use the new feature in a puzzle; perhaps in the further future it might make sense to migrate all the puzzles to the new API and stop providing back ends with two alternative ways of doing things, but this seemed like enough upheaval for one day.
* Giant const patch of doom: add a 'const' to every parameter in everySimon Tatham2013-04-13
| | | | | | | | | | | | | | puzzle backend function which ought to have it, and propagate those consts through to per-puzzle subroutines as needed. I've recently had to do that to a few specific parameters which were being misused by particular puzzles (r9657, r9830), which suggests that it's probably a good idea to do the whole lot pre-emptively before the next such problem shows up. [originally from svn r9832] [r9657 == 3b250baa02a7332510685948bf17576c397b8ceb] [r9830 == 0b93de904a98f119b1a95d3a53029f1ed4bfb9b3]
* Add 'const' to the game_params arguments in validate_desc andSimon Tatham2013-04-12
| | | | | | | | | | | | new_desc. Oddities in the 'make test' output brought to my attention that a few puzzles have been modifying their input game_params for various reasons; they shouldn't do that, because that's the game_params held permanently by the midend and it will affect subsequent game generations if they modify it. So now those arguments are const, and all the games which previously modified their game_params now take a copy and modify that instead. [originally from svn r9830]
* New rule: interpret_move() is passed a pointer to the game_drawstateSimon Tatham2012-09-09
| | | | | | | | | | | | | | | | basically just so that it can divide mouse coordinates by the tile size, but is definitely not expected to _write_ to it, and it hadn't previously occurred to me that anyone might try. Therefore, interpret_move() now gets a pointer to a _const_ game_drawstate instead of a writable one. All existing puzzles cope fine with this API change (as long as the new const qualifier is also added to a couple of subfunctions to which interpret_move delegates work), except for the just-committed Undead, which somehow had ds->ascii and ui->ascii the wrong way round but is otherwise unproblematic. [originally from svn r9657]
* Changed my mind about midend_is_solved: I've now reprototyped it asSimon Tatham2011-06-19
| | | | | | | | | | | | | | | | midend_status(), and given it three return codes for win, (permanent) loss and game-still-in-play. Depending on what the front end wants to use it for, it may find any or all of these three states worth distinguishing from each other. (I suppose a further enhancement might be to add _non_-permanent loss as a fourth distinct status, to describe situations in which you can't play further without pressing Undo but doing so is not completely pointless. That might reasonably include dead-end situations in Same Game and Pegs, and blown-self-up situations in Mines and Inertia. However, I haven't done this at present.) [originally from svn r9179]
* Fix warnings generated by gcc 4.6.0 about variables set but notSimon Tatham2011-05-04
| | | | | | | | | | thereafter read. Most of these changes are just removal of pointless stuff or trivial reorganisations; one change is actually substantive, and fixes a bug in Keen's clue selection (the variable 'bad' was unreferenced not because I shouldn't have set it, but because I _should_ have referenced it!). [originally from svn r9164]
* Add a function to every game backend which indicates whether a gameSimon Tatham2011-04-02
| | | | | | | | | | | state is in a solved position, and a midend function wrapping it. (Or, at least, a situation in which further play is pointless. The point is, given that game state, would it be a good idea for a front end that does that sort of thing to proactively provide the option to start a fresh game?) [originally from svn r9140]
* More defensive-coding fixes from James H.Simon Tatham2009-07-01
| | | | [originally from svn r8605]
* Lee Dowling points out that duplicating the entire grid dataSimon Tatham2009-02-05
| | | | | | | | structure in every game_state is terribly wasteful. Move all the constant bits of it (i.e. everything except the per-square 'blue' flag) into a ref-counted shared structure. [originally from svn r8444]
* Patch from James H providing lots more paranoid casting. Also oneSimon Tatham2008-09-13
| | | | | | | | | | actual behaviour change: Untangle now permits dragging with the right mouse button, which has exactly the same effect as it does with the left. (Harmless on desktop platforms, but helpful when "right-click" is achieved by press-and-hold; now the drag takes place even if you hesitate first.) [originally from svn r8177]
* New infrastructure feature. Games are now permitted to beSimon Tatham2008-09-06
| | | | | | | | | | | | | | | | | | | | | | _conditionally_ able to format the current puzzle as text to be sent to the clipboard. For instance, if a game were to support playing on a square grid and on other kinds of grid such as hexagonal, then it might reasonably feel that only the former could be sensibly rendered in ASCII art; so it can now arrange for the "Copy" menu item to be greyed out depending on the game_params. To do this I've introduced a new backend function (can_format_as_text_now()), and renamed the existing static backend field "can_format_as_text" to "can_format_as_text_ever". The latter will cause compile errors for anyone maintaining a third-party front end; if any such person is reading this, I apologise to them for the inconvenience, but I did do it deliberately so that they'd know to update their front end. As yet, no checked-in game actually uses this feature; all current games can still either copy always or copy never. [originally from svn r8161]
* HTML Help support for Puzzles, with the same kind of automaticSimon Tatham2006-12-24
| | | | | | fallback behaviour as PuTTY's support. [originally from svn r7009]
* Cleanup: it was absolutely stupid for game_wants_statusbar() to be aSimon Tatham2005-10-22
| | | | | | | | | function, since it took no parameters by which to vary its decision, and in any case it's hard to imagine a game which only _conditionally_ wants a status bar. Changed it into a boolean data field in the backend structure. [originally from svn r6417]
* Cleanup: remove the game_state parameter to game_colours(). No gameSimon Tatham2005-10-22
| | | | | | | | | | | | was actually using it, and also it wasn't being called again for different game states or different game parameters, so it would have been a mistake to depend on anything in that game state. Games are now expected to commit in advance to a single fixed list of all the colours they will ever need, which was the case in practice already and simplifies any later port to a colour-poor platform. Also this change has removed a lot of unnecessary faff from midend_colours(). [originally from svn r6416]
* Cleanup: the `mouse_priorities' field in the back end has been aSimon Tatham2005-10-22
| | | | | | | more general-purpose flags word for some time now. Rename it to `flags'. [originally from svn r6414]
* Substantial infrastructure upheaval. I've separated the drawing APISimon Tatham2005-08-18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | as seen by the back ends from the one implemented by the front end, and shoved a piece of middleware (drawing.c) in between to permit interchange of multiple kinds of the latter. I've also added a number of functions to the drawing API to permit printing as well as on-screen drawing, and retired print.py in favour of integrated printing done by means of that API. The immediate visible change is that print.py is dead, and each puzzle now does its own printing: where you would previously have typed `print.py solo 2x3', you now type `solo --print 2x3' and it should work in much the same way. Advantages of the new mechanism available right now: - Map is now printable, because the new print function can make use of the output from the existing game ID decoder rather than me having to replicate all those fiddly algorithms in Python. - the new print functions can cope with non-initial game states, which means each puzzle supporting --print also supports --with-solutions. - there's also a --scale option permitting users to adjust the size of the printed puzzles. Advantages which will be available at some point: - the new API should permit me to implement native printing mechanisms on Windows and OS X. [originally from svn r6190]
* Quite a few instances of the Cardinal Error of Ctype were turned upSimon Tatham2005-07-17
| | | | | | by a grep I just did. Oops. [originally from svn r6113]
* game_timing_state() now has access to the game_ui. This means thatSimon Tatham2005-07-10
| | | | | | | | | | | | whether the timer is currently going is no longer solely dependent on the current game_state: it can be dependent on more persistent information stored in the game_ui. In particular, Mines now freezes the timer permanently once you complete a grid for the first time, so that you can then backtrack through your solution process without destroying the information about how long it took you the first time through. [originally from svn r6088]
* Add a `full' parameter to validate_params(), analogous to the one inJacob Nevins2005-07-05
| | | | | | | | | | | encode_params(). This is necessary for cases where generation-time parameters that are normally omitted from descriptive IDs can place restrictions on other parameters; in particular, when the default value of a relevant generation-time parameter is not the one used to generate the descriptive ID, validation could reject self-generated IDs (e.g., Net `5x2w:56182ae7c2', and some cases in `Pegs'). [originally from svn r6068]
* Refactored the game_size() interface, which was getting reallySimon Tatham2005-07-05
| | | | | | | | | | | | | unpleasant and requiring lots of special cases to be taken care of by every single game. The new interface exposes an integer `tile size' or `scale' parameter to the midend and provides two much simpler routines: one which computes the pixel window size given a game_params and a tile size, and one which is given a tile size and must set up a drawstate appropriately. All the rest of the complexity is handled in the midend, mostly by binary search, so grubby special cases only have to be dealt with once. [originally from svn r6059]
* draw_polygon() and draw_circle() have always had a portabilitySimon Tatham2005-07-03
| | | | | | | | | | | | | | | | | | | constraint: because some front ends interpret `draw filled shape' to mean `including its boundary' while others interpret it to mean `not including its boundary' (and X seems to vacillate between the two opinions as it moves around the shape!), you MUST NOT draw a filled shape only. You can fill in one colour and outline in another, you can fill or outline in the same colour, or you can just outline, but just filling is a no-no. This leads to a _lot_ of double calls to these functions, so I've changed the interface. draw_circle() and draw_polygon() now each take two colour arguments, a fill colour (which can be -1 for none) and an outline colour (which must be valid). This should simplify code in the game back ends, while also reducing the possibility for coding error. [originally from svn r6047]
* New {en,de}code_ui functions should be static. Oops.Simon Tatham2005-06-28
| | | | [originally from svn r6031]
* More serialisation changes: the game_aux_info structure has now beenSimon Tatham2005-06-28
| | | | | | | | | | | | retired, and replaced with a simple string. Most of the games which use it simply encode the string in the same way that the Solve move will also be encoded, i.e. solve_game() simply returns dupstr(aux_info). Again, this is a better approach than writing separate game_aux_info serialise/deserialise functions because doing it this way is self-testing (the strings are created and parsed during the course of any Solve operation at all). [originally from svn r6029]
* Another function pair required for serialisation; these ones saveSimon Tatham2005-06-28
| | | | | | | | | | | and restore anything vitally important in the game_ui. Most of the game_ui is expected to be stuff about cursor positions and currently active mouse drags, so it absolutely _doesn't_ want to be preserved over a serialisation; but one or two things would be disorienting or outright wrong to reset, such as the Net origin position and the Mines death counter. [originally from svn r6026]
* Re-architecting of the game backend interface. make_move() has beenSimon Tatham2005-06-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | split into two functions. The first, interpret_move(), takes all the arguments that make_move() used to get and may have the usual side effects of modifying the game_ui, but instead of returning a modified game_state it instead returns a string description of the move to be made. This string description is then passed to a second function, execute_move(), together with an input game_state, which is responsible for actually producing the new state. (solve_game() also returns a string to be passed to execute_move().) The point of this is to work towards being able to serialise the whole of a game midend into a byte stream such as a disk file, which will eventually support save and load functions in the desktop puzzles, as well as restoring half-finished games after a quit and restart in James Harvey's Palm port. Making each game supply a convert-to-string function for its game_state format would have been an unreliable way to do this, since those functions would not have been used in normal play, so they'd only have been tested when you actually tried to save and load - a recipe for latent bugs if ever I heard one. This way, you won't even be able to _make_ a move if execute_move() doesn't work properly, which means that if you can play a game at all I can have pretty high confidence that serialising it will work first time. This is only the groundwork; there will be more checkins to come on this theme. But the major upheaval should now be done, and as far as I can tell everything's still working normally. [originally from svn r6024]
* Infrastructure change which I've been thinking about for a while:Simon Tatham2005-06-17
| | | | | | | the back end function solve_game() now takes the _current_ game_state in addition to the initial one. [originally from svn r5969]
* All the games in this collection have always defined their graphicsSimon Tatham2005-06-07
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | in terms of a constant TILE_SIZE (or equivalent). Here's a surprisingly small patch which switches this constant into a run-time variable. The only observable behaviour change should be on Windows, which physically does not permit the creation of windows larger than the screen; if you try to create a puzzle (Net makes this plausible) large enough to encounter this restriction, the Windows front end should automatically re-adjust the puzzle's tile size so that it does fit within the available space. On GTK, I haven't done this, on the grounds that X _does_ permit windows larger than the screen, and many X window managers already provide the means to navigate around such a window. Gareth said he'd rather navigate around a huge Net window than have it shrunk to fit on one screen. I'm uncertain that this makes sense for all puzzles - Pattern in particular strikes me as something that might be better off shrunk to fit - so I may have to change policy later or make it configurable. On OS X, I also haven't done automatic shrinkage to fit on one screen, largely because I didn't have the courage to address the question of multiple monitors and what that means for the entire concept :-) [originally from svn r5913]
* Introduce a new game backend function (there seem to have been a lotSimon Tatham2005-06-06
| | | | | | | | | | | | | | | | | | | of these recently) whose job is to update a game_ui to be consistent with a new game_state. This is called by midend.c in every situation where the current game_state changes _other_ than as a result of make_move (Undo, Redo, Restart, Solve). The introduction of this function allows a game_ui to contain information about selections or highlights within a game_state which simply wouldn't make sense when transferred to another game_state. In particular, I've used it to fix a subtle bug in Solo whereby, although you couldn't right-click to pencil-mode highlight a filled square, you could _get_ a pencil-mode highlight in a filled square if you used Undo and Redo. (Undo to before the square was filled, right-click to highlight it, then Redo. Alternatively, left-click and clear the square, right-click to highlight it, then Undo.) [originally from svn r5912]
* Miscellaneous fixes from James Harvey's PalmOS porting work:Simon Tatham2005-06-01
| | | | | | | | | | | | | | | | | | | | - fixed numerous memory leaks (not Palm-specific) - corrected a couple of 32-bit-int assumptions (vital for Palm but generally a good thing anyway) - lifted a few function pointer types into explicit typedefs (neutral for me but convenient for the source-munging Perl scripts he uses to deal with Palm code segment rules) - lifted a few function-level static arrays into global static arrays (neutral for me but apparently works round a Palm tools bug) - a couple more presets in Rectangles (so that Palm, or any other slow platform which can't handle the larger sizes easily, can still have some variety available) - in Solo, arranged a means of sharing scratch space between calls to nsolve to prevent a lot of redundant malloc/frees (gives a 10% speed increase even on existing platforms) [originally from svn r5897]
* Better mouse button handling in Mines:Simon Tatham2005-05-31
| | | | | | | | | | | | | - middle button now also triggers the clear-around-square action - a special-case handler in midend_process_key() arranges that the left button always trumps the right button if both are pressed together, meaning that Windows Minesweeper players used to pressing L+R to clear around a square should still be able to do so without any strange behaviour. (The latter touches all game backends, yet again, to add a field to the game structure which is zero in everything except Mines.) [originally from svn r5888]
* Move definition of PI into puzzles.h. If nothing else, the definition in cube.cJacob Nevins2005-05-31
| | | | | | had a typo :) [originally from svn r5878]
* Mouse-based interface for Cube: you left-click anywhere on the gridSimon Tatham2005-05-31
| | | | | | | | | | | | | | | and it moves the polyhedron in the general direction of the mouse pointer. (I had this in my initial throwaway Python implementation of this game, but never reimplemented it in this version. It's harder with triangles, but not too much harder.) Since the logical-to-physical coordinate mapping in Cube is dynamically computed, this has involved an interface change which touches all puzzles: make_move() is now passed a pointer to the game_drawstate, which it may of course completely ignore if it wishes. [originally from svn r5877]
* Added an `interactive' flag to new_game_desc(), which toggles MinesSimon Tatham2005-05-30
| | | | | | | | | between on the one hand generating indeterminate game descriptions awaiting the initial click, and on the other hand generating concrete ones which have had their initial click. This makes `mines --generate' do something useful. [originally from svn r5869]
* First cut at a game timer. Yet another backend function whichSimon Tatham2005-05-30
| | | | | | | | | | | | | | | indicates whether a particular game state should have the timer going (for Mines the initial indeterminate state does not have this property, and neither does a dead or won state); a midend function that optionally (on request from the game) prepends a timer to the front of the status bar text; some complicated midend timing code. It's not great. It's ugly; it's probably slightly inaccurate; it's got no provision for anyone but the game author decreeing whether a game is timed or not. But Mines can't be taken seriously without a timer, so it's a start. [originally from svn r5866]
* Mines now follows the conventional approach of offering a completelySimon Tatham2005-05-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | blank grid until you make the first click; to ensure solubility, it does not generate the mine layout until that click, and then ensures it is solvable starting from that position. This has involved three infrastructure changes: - random.c now offers functions to encode and decode an entire random_state as a string - each puzzle's new_game() is now passed a pointer to the midend itself, which most of them ignore - there's a function in the midend which a game can call back to _rewrite_ its current game description. So Mines now has two entirely separate forms of game ID. One contains the generation-time parameters (n and unique) plus an encoding of a random_state; the other actually encodes the grid once it's been generated, and also contains the initial click position. When called with the latter, new_game() does plausibly normal stuff. When called with the former, it notes down all the details and waits until the first square is opened, and _then_ does the grid generation and updates the game description in the midend. So if, _after_ your first click, you decide you want to share this particular puzzle with someone else, you can do that fine. Also in this checkin, the mine layout is no longer _copied_ between all the game_states on the undo chain. Instead, it's in a separate structure and all game_states share a pointer to it - and the structure is reference-counted to ensure deallocation. [originally from svn r5862]
* Infrastructure change: game_anim_length and game_flash_length nowSimon Tatham2005-05-30
| | | | | | | | | both get passed a pointer to the game_ui. This means that if they need to note down information for the redraw function about what _type_ of flash or animation is required, they now have somewhere to do so. [originally from svn r5858]
* Add origin-shifting (Shift+cursors) and source-shifting (Ctrl+cursors) to Net.Jacob Nevins2005-05-26
| | | | | | | | | | | | (Adding modifier+cursors handling has had minor knock-on effects on the other puzzles, so that they can continue to ignore modifiers.) (An unfortunate side effect of this is some artifacts in exterior barrier drawing; notably, a disconnected corner can now appear at the corner of the grid under some circumstances. I haven't found a satisfactory way round this yet.) [originally from svn r5844]
* Cube's dup_game() function was missing a field. Oops.Simon Tatham2005-05-17
| | | | [originally from svn r5789]
* The game IDs for Net (and Netslide) have always been random seedsSimon Tatham2005-05-16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | rather than literal grid descriptions, which has always faintly annoyed me because it makes it impossible to type in a grid from another source. However, Gareth pointed out that short random-seed game descriptions are useful, because you can read one out to someone else without having to master the technology of cross- machine cut and paste, or you can have two people enter the same random seed simultaneously in order to race against each other to complete the same puzzle. So both types of game ID seem to have their uses. Therefore, here's a reorganisation of the whole game ID concept. There are now two types of game ID: one has a parameter string then a hash then a piece of arbitrary random seed text, and the other has a parameter string then a colon then a literal game description. For most games, the latter is identical to the game IDs that were previously valid; for Net and Netslide, old game IDs must be translated into new ones by turning the colon into a hash, and there's a new descriptive game ID format. Random seed IDs are not guaranteed to be portable between software versions (this is a major reason why I added version reporting yesterday). Descriptive game IDs have a longer lifespan. As an added bonus, I've removed the sections of documentation dealing with game parameter encodings not shown in the game ID (Rectangles expansion factor, Solo symmetry and difficulty settings etc), because _all_ parameters must be specified in a random seed ID and therefore users can easily find out the appropriate parameter string for any settings they have configured. [originally from svn r5788]
* I've had two complaints that Solo ought to recognise the numericSimon Tatham2005-05-12
| | | | | | | | | | | | | | | | keypad. The reason it doesn't is because front ends were carefully translating the numeric keypad into 8-way directional keys for the benefit of Cube. Therefore, a policy change: - front ends process the numeric keypad by sending MOD_NUM_KEYPAD | '3' and similar - front ends running on a platform with Num Lock SHOULD do this _irrespective_ of the state of Num Lock - back ends do whatever they see fit with numeric keypad keys. Result: the numeric keypad now works in Solo, and also works in OS X Cube (which it previously didn't because I forgot to implement that bit of the front end!). [originally from svn r5774]
* Silly (but harmless) typo.Simon Tatham2005-05-02
| | | | [originally from svn r5732]