Skip to content

Commit

Permalink
Create blocks to customize screen layout
Browse files Browse the repository at this point in the history
Added blocks to allow setting position and size of dialogs:
- It is possible to configure text windows and menus separately;
- It is possible to set the `x` and `y` coordinates of the dialogs;
- It is possible to set the `width` and `height` of the dialogs;
- It is possible to set those informations in `characters` or in `percentage`;
- When a negative value is informed to the `x` coordinate, it is understood as "count the position from the right, instead of the left";
- When a negative value is informed to the `y` coordinate, it is understood as "count the position from the bottom, instead of the top".

Merge pull request #40 from haroldo-ok/screen-layout
  • Loading branch information
haroldo-ok authored Oct 23, 2022
2 parents 749f41a + e13b157 commit e297ee6
Show file tree
Hide file tree
Showing 8 changed files with 379 additions and 72 deletions.
151 changes: 130 additions & 21 deletions blockly/apps/blocklyduino/base-project/src/vn_engine.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
#include <stdio.h>
#include <stdarg.h>

#include "unity.h"
#include "vn_engine.h"

#define MSG_COL_COUNT (CHR_COLS - 2)
#define MSG_LINE_COUNT 4
#define MENU_ENTRY_COUNT 8

typedef struct _menuEntry {
Expand All @@ -16,8 +13,17 @@ typedef struct _menuEntry {
menuEntry menuEntries[MENU_ENTRY_COUNT];
unsigned char usedMenuEntries;
unsigned char menuCursor;
struct {
unsigned char x, y;
unsigned char width, height;
} menuConfig;

struct {
unsigned char x, y;
unsigned char width, height;
unsigned char** lines;
} msgLines;

unsigned char* msgLines[MSG_LINE_COUNT];
char characterName[32];

char *backgroundImage;
Expand All @@ -39,17 +45,17 @@ unsigned char addMenuItem(char *s) {
}

unsigned char menuTop() {
return (CHR_ROWS - usedMenuEntries - 2) >> 1;
return menuConfig.y - (usedMenuEntries >> 1);
}

void drawMenuLine(int number) {
int y = menuTop() + number - 1;
#ifdef __LYNX__
PrintStr(1, y, number == menuCursor ? "*" : " ");
PrintStr(menuConfig.x, y, number == menuCursor ? "*" : " ");
#else
PrintNum(1, y, number);
PrintNum(menuConfig.x, y, number);
#endif
PrintStr(3, y, menuEntries[number - 1].s);
PrintStr(menuConfig.x + 2, y, menuEntries[number - 1].s);
}

unsigned char drawMenu() {
Expand All @@ -58,7 +64,7 @@ unsigned char drawMenu() {
char selected;

y = menuTop();
Panel(1, y - 1, CHR_COLS - 2, usedMenuEntries + 1, "");
Panel(menuConfig.x, y - 1, menuConfig.width, usedMenuEntries + 1, "");

for (i = 1; i <= usedMenuEntries; i++) {
drawMenuLine(i);
Expand All @@ -83,15 +89,15 @@ char *bufferWrappedTextLine(char *s, char x, char y, char w) {

// Skips initial spaces for current line
for (o = startOfLine; *o == ' '; o++) {
msgLines[y][tx] = ' ';
msgLines.lines[y][tx] = ' ';
tx++;
currW++;
bestW = currW;
}
startOfLine = o;

if (!*o || currW >= w) {
msgLines[y][tx] = 0;
msgLines.lines[y][tx] = 0;
return 0;
}

Expand Down Expand Up @@ -120,7 +126,7 @@ char *bufferWrappedTextLine(char *s, char x, char y, char w) {
for (o = startOfLine; o <= endOfLine; o++) {
ch = *o;
if (ch && ch != '\n') {
msgLines[y][tx] = ch;
msgLines.lines[y][tx] = ch;
tx++;
}
}
Expand All @@ -135,7 +141,7 @@ char *bufferWrappedTextLine(char *s, char x, char y, char w) {
endOfLine++;
}

msgLines[y][tx] = 0;
msgLines.lines[y][tx] = 0;
return *endOfLine ? endOfLine : 0;
}

Expand All @@ -152,11 +158,35 @@ char *bufferWrappedText(char *s, char x, char y, char w, char h) {
return o;
}

void bufferResize(char width, char height) {
unsigned char i;

// Deallocate existing buffers
if (msgLines.lines) {
for (i = 0; i != msgLines.height; i++) {
free(msgLines.lines[i]);
}
free(msgLines.lines);
msgLines.lines = 0;
}

// Reallocate according to the new size

msgLines.width = width;
msgLines.height = height;
msgLines.lines = calloc(msgLines.height, sizeof(char *));

for (i = 0; i != msgLines.height; i++) {
msgLines.lines[i] = malloc(msgLines.width + 1);
msgLines.lines[i][0] = 0;
}
}

void bufferClear() {
unsigned char i;

for (i = 0; i != MSG_LINE_COUNT; i++) {
msgLines[i][0] = 0;
for (i = 0; i != msgLines.height; i++) {
msgLines.lines[i][0] = 0;
}
}

Expand Down Expand Up @@ -198,11 +228,16 @@ void initGfx() {
InitBitmap();

EnterBitmapMode();
}

int convertCoordinate(int coord, int max, char unit) {
// Percent to chars
if (unit == WND_UNIT_PERCENT) coord = coord * max / 100;

for (i = 0; i != MSG_LINE_COUNT; i++) {
msgLines[i] = malloc(MSG_COL_COUNT);
}
bufferClear();
// Negative coordinates
if (coord < 0) coord = max + coord;

return coord;
}

void initVN() {
Expand All @@ -212,6 +247,10 @@ void initVN() {

backgroundImage = 0;
actorImage = 0;

msgLines.lines = 0;
vnWindowReset();

strcpy(characterName, "");
}

Expand All @@ -229,16 +268,86 @@ void vnChar(char *charName) {
strcpy(characterName, charName);
}

void vnWindowFrom(char target, int x, int y, char unit) {
x = convertCoordinate(x, CHR_COLS, unit);
y = convertCoordinate(y, CHR_ROWS, unit);

if (target == WND_TARGET_MENU) {
menuConfig.x = x;
menuConfig.y = y;
} else {
msgLines.x = x;
msgLines.y = y;
}
}

void vnWindowSize(char target, int width, int height, char unit) {
if (width < 0) {
if (target == WND_TARGET_MENU) {
menuConfig.x -= convertCoordinate(width, CHR_COLS, unit);
} else {
msgLines.x -= convertCoordinate(width, CHR_COLS, unit);
}
width = -width;
}

if (height < 0) {
if (target == WND_TARGET_MENU) {
menuConfig.y -= convertCoordinate(height, CHR_ROWS, unit);
} else {
msgLines.y -= convertCoordinate(height, CHR_ROWS, unit);
}
height = -height;
}

width = convertCoordinate(width, CHR_COLS, unit);
height = convertCoordinate(height, CHR_ROWS, unit);

if (target == WND_TARGET_MENU) {
menuConfig.width = width;
menuConfig.height = height;
} else {
bufferResize(width, height);
}
}

void vnWindowTo(char target, int x, int y, char unit) {
int width, height;

x = convertCoordinate(x, CHR_COLS, unit);
y = convertCoordinate(y, CHR_ROWS, unit);

if (target == WND_TARGET_MENU) {
width = x - menuConfig.x + 1;
height = y - menuConfig.y + 1;
} else {
width = x - msgLines.x + 1;
height = y - msgLines.y + 1;
}

vnWindowSize(target, width, height, WND_UNIT_CHARS);
}

void vnWindowReset() {
// Text window
vnWindowFrom(WND_TARGET_TEXT, 1, -8, WND_UNIT_CHARS);
vnWindowSize(WND_TARGET_TEXT, CHR_COLS - 2, 4, WND_UNIT_CHARS);

// Menu window
vnWindowFrom(WND_TARGET_MENU, 1, (CHR_ROWS - 2) >> 1, WND_UNIT_CHARS);
vnWindowSize(WND_TARGET_MENU, CHR_COLS - 2, MENU_ENTRY_COUNT, WND_UNIT_CHARS);
}

void vnText(char *text) {
char *textToDisplay;

for (textToDisplay = text; textToDisplay;) {
waitNextButtonRelease();

bufferClear();
textToDisplay = bufferWrappedText(textToDisplay, 0, 0, MSG_COL_COUNT, MSG_LINE_COUNT);
textToDisplay = bufferWrappedText(textToDisplay, 0, 0, msgLines.width, msgLines.height);

ListBox(1, CHR_ROWS - MSG_LINE_COUNT - 4, MSG_COL_COUNT, MSG_LINE_COUNT + 2, characterName, msgLines, MSG_LINE_COUNT);
ListBox(msgLines.x, msgLines.y, msgLines.width, msgLines.height + 2, characterName, msgLines.lines, msgLines.height);

#ifdef __LYNX__
// Wait until the joystick button is pressed
Expand Down
12 changes: 12 additions & 0 deletions blockly/apps/blocklyduino/base-project/src/vn_engine.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
#ifndef _VN_ENGINE_H
#define _VN_ENGINE_H

#define WND_TARGET_TEXT (1)
#define WND_TARGET_MENU (2)
#define WND_UNIT_CHARS (1)
#define WND_UNIT_PERCENT (2)

extern void initVN();

extern void vnWindowFrom(char target, int x, int y, char unit);
extern void vnWindowSize(char target, int width, int height, char unit);
extern void vnWindowTo(char target, int x, int y, char unit);
extern void vnWindowTo(char target, int x, int y, char unit);
extern void vnWindowReset();

extern void vnScene(char *scene);
extern void vnShow(char *actor);
extern void vnChar(char *charName);
Expand Down
2 changes: 2 additions & 0 deletions blockly/apps/blocklyduino/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,8 @@ <h3>
<field name="SOURCE"></field>
<field name="IMAGE">./img/portrait_placeholder.png</field>
</block>
<block type="vn_window"></block>
<block type="vn_window_reset"></block>
</category>
<category name="Menu">
<block type="menu"></block>
Expand Down
46 changes: 46 additions & 0 deletions blockly/blocks/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,49 @@ Blockly.Blocks['vn_character'] = {
}
}
};

Blockly.Blocks['vn_window'] = {
init: function() {
var TARGETS = [
['text', 'TEXT'],
['menu', 'MENU']
];

var COMMANDS = [
['starting at', 'STARTING_AT'],
['ending at', 'ENDING_AT'],
['size', 'SIZE']
];

var UNITS = [
['in chars', 'CHARS'],
['%', 'PERCENT']
];

this.setColour(230);
this.appendDummyInput()
.appendField('Window for')
.appendField(new Blockly.FieldDropdown(TARGETS), 'TARGET')
.appendField(new Blockly.FieldDropdown(COMMANDS), 'COMMAND')
.appendField('(')
.appendField(new Blockly.FieldTextInput('0', Blockly.FieldTextInput.numberValidator), 'X')
.appendField(',')
.appendField(new Blockly.FieldTextInput('0', Blockly.FieldTextInput.numberValidator), 'Y')
.appendField(')')
.appendField(new Blockly.FieldDropdown(UNITS), 'UNIT');
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip('Configures window coordinates.');
}
};

Blockly.Blocks['vn_window_reset'] = {
init: function() {
this.setColour(230);
this.appendDummyInput()
.appendField('Window reset');
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip('Resets window coordinates.');
}
};
26 changes: 26 additions & 0 deletions blockly/generators/arduino/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,29 @@ Blockly.Arduino.vn_character = function() {
var code = 'vnChar(' + charName + ');\n';
return code;
}

Blockly.Arduino.vn_window = function() {
var COMMAND_MAP = {
'STARTING_AT': 'vnWindowFrom',
'ENDING_AT': 'vnWindowTo',
'SIZE': 'vnWindowSize'
};

var target = this.getFieldValue('TARGET');
var command = this.getFieldValue('COMMAND');
var x = window.parseFloat(this.getFieldValue('X'));
var y = window.parseFloat(this.getFieldValue('Y'));
var unit = this.getFieldValue('UNIT');

var code = COMMAND_MAP[command] + '(' +
'WND_TARGET_' + target + ',' +
x + ',' + y + ',' +
'WND_UNIT_' + unit +
');\n';
return code;
}

Blockly.Arduino.vn_window_reset = function() {
var code = 'vnWindowReset();\n';
return code;
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "BlocklyVN8bit",
"version": "0.2.8",
"version": "0.3.0",
"description": "Uses blockly to generate visual novels for 8bit-Unity",
"main": "main.js",
"scripts": {
Expand Down
Loading

0 comments on commit e297ee6

Please sign in to comment.